2011-10-01 17 views
5

Estoy aprendiendo Java y encuentro algunos problemas. Aquí tenemos patrón de la fábrica simple:Registro de fábrica automático

public class SomeFactory { 
    ... 
    public static void registerProduct(String name, Class<? extends IProduct > f) 
} 

public SomeProduct implements IProduct { 
    static { 
     SomeFactory.register("some product", SomeProduct.class); 
    } 
    ... 
} 

Todos los productos deben inscribirse en la fábrica.

Pero antes de usar este código, todas las clases de productos deben cargarse. Puedo poner Class.forName() en alguna parte, por ejemplo en la función principal. Pero quiero evitar ese tipo de carga manual de clases. Solo quiero agregar nuevas implementaciones IProduct , sin actualizar otras partes (como los métodos SomeFactory o Main, etc.). Pero me pregunto, ¿es posible cargar algunas clases automáticamente (marcadas con una anotación, por ejemplo)?

P.S Quiero notar que no se agregarán otras clases en el tiempo de ejecución, todas las implementaciones de IProduct son conocidas antes de la compilación.

UPD # 1 Gracias por su respuesta! ¿Pero es posible crear automáticamente un archivo de propiedades con IProduct instancias? Quiero decir, ¿es posible crear algún script de compilación (para maven, por ejemplo) que genere código de propiedad o código de cargador? ¿Hay tales soluciones o marcos?

UPD # 2 he terminado con el uso de Reflections library que proporciona información en tiempo de ejecución, mediante el escaneo de ruta de clase en el arranque.

Respuesta

5

Esto es posible, pero no es fácil. Tendría que analizar todas las clases en la ruta de clase para ver si tienen una anotación o implementar la interfaz IProduct. Ver How do you find all subclasses of a given class in Java? para respuestas a tal problema.

Lo mantendría simple y solo tendré una lista de clases para cargar, ya sea en la fábrica misma o en un archivo externo (archivo de propiedades, por ejemplo).

3
  1. Haga que cada producto registrarse a sí mismo, usando un bloque estático como sigue:

    class MyProduct1{ 
    
        static{ 
         SomeFactory.register(this.getClass()); 
        } 
        .. 
        .. 
    } 
    
  2. Un archivo de propiedades externo puede realizar un seguimiento de todos los productos.

  3. Su método principal puede analizar esta lista de Productos y hacer un Class.forName ("..").

De esta manera no necesitarás codificar ningún producto específico, solo el archivo de propiedad cambia constantemente. Ah! sí, agregar registro de seguridad también sería un punto a favor.

Nota: Sólo estoy proponiendo una idea, I'vent probado a mí mismo :)

+6

Cómo es 'this.getClass()' va a trabajar en '' estática {} ... O_O? –

Cuestiones relacionadas