2012-07-09 7 views
9

Estoy creando una biblioteca de Java, como un producto final en la intención de distribuir este .jar a los desarrolladores.Alcance de clase de Java y biblioteca

Estoy "traduciendo" mi biblioteca de Objective-C donde controlo los archivos de cabecera de clases disponibles para el desarrollador. En otras palabras, solo estoy exponiendo al desarrollador algunas clases que pueden manejar.

En mi biblioteca Java estoy usando paquetes y mi paquete ha crecido bastante. Así que decidí separar en diferentes paquetes mis modelos y controladores. Pero ahora los modelos que quería mantener en privado deben marcarse como públicos para usarlos desde el paquete principal.

Mi pregunta es, ¿esto va en contra de lo que estaba haciendo en Objective-C?

Por ejemplo, tengo una clase de evento que realmente solo se usa internamente y no quiero que el usuario lo sepa ni lo piense. Tengo otra clase TimedEvent, que el usuario puede obtener una instancia de una gestión.

En mi Objective-C, simplemente excluí la clase de evento del ámbito público de la biblioteca, lo que permite TimedEvent.

Si estoy haciendo las cosas más ordenadas en mi biblioteca, entonces parece que los paquetes no son el camino. Desde ahora, mi controlador principal está en el paquete principal y todos los modelos están en otro paquete, forzado a tener un alcance público.

Opiniones?

Respuesta

5

Esto es posible con Java, pero hay razones por las que (casi) nadie lo hace ...

Si ponemos la aplicación y la interfaz en el mismo paquete, entonces se puede omitir todos los modificadores de acceso (private , protected, public) de clases y métodos para darles visibilidad "predeterminada" o "paquete": solo las clases en el mismo paquete pueden verlas/usarlas.

Desventaja: Deberá mezclar API e implementación.

El otro enfoque es mover la implementación a un paquete *.private.*. No más mezcla de API e implementación, pero los usuarios maliciosos pueden acceder fácilmente a la implementación, es solo una convención de nomenclatura. Como un STOP: Significa algo ("ten cuidado") pero no te detiene.

Por último, puede implementar la interfaz dentro de la interfaz. Por ejemplo:

public interface IFoo { 
    String getName(); 

    private static class Foo implements IFoo { 
     public String getName(); 
    } 

    public static class FooFactory { 
     public static IFoo create() { return new Foo(); } 
    } 
} 

Ugly, ¿o no?

+2

buen toque sobre la aplicación dentro de la interfaz. Es esa una nueva característica? –

+1

No, eso funciona porque Java admite clases internas (1.2, creo) pero agrega mucho código de placa de caldera. –

+0

Muchos libros de texto lo han equivocado. "Interfaz: constantes y declaraciones de métodos" –

4

El enfoque común para controlar la exposición de sus clases al mundo es ocultar las implementaciones detrás de las interfaces y las fábricas.

  • Crear una interfaz para su TimedEvent, y una clase para la creación de instancias de TimedEvent interfaz
  • Ponga la interfaz en el paquete principal, y la fábrica en un sub-paquete
  • Dar la visibilidad pública de fábrica
  • implementar la interfaz en la sub-paquete, dándole visibilidad empaquetar
  • Crear una instancia de la clase que implementa la interfaz TimedEvent en la fábrica

Aquí es un ejemplo de cómo puede hacerlo:

package com.my.main; 
public interface TimedEvent { 
    void fire(); 
} 

package com.my.main.events; 
import com.my.main; 
public class EventFactory { 
    public TimedEvent makeTimedEvent() { return new TimedEvent(); } 
} 
// TimedEventImpl has package visibility - it is not public. 
class TimedEventImpl implements TimedEvent { 
    public void fire() { 
     // Fire a timed event 
    } 
} 

Los usuarios podrían acceder TimedEvent así:

com.my.main.events.EventFactory f = new com.my.main.events.EventFactory(); 
com.my.main.TimedEvent evt = f.makeTimedEvent(); 
evt.fire();