2011-10-01 19 views
5

sto solo imparando java e ho riscontrato alcuni problemi. Qui abbiamo semplice modello di fabbrica:Registrazione automatica di fabbrica

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

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

Tutti i prodotti devono registrarsi in fabbrica.

Ma prima di utilizzare questo codice, tutte le classi di prodotti devono essere caricate. Posso mettere Class.forName() da qualche parte, per esempio nella funzione principale. Ma voglio evitare questo tipo di caricamento di classi manuali. Voglio solo aggiungere nuove implementazioni , senza aggiornare altre parti (come ad esempio i metodi SomeFactory o Main, ecc.). Ma mi chiedo, è possibile caricare automaticamente alcune classi (contrassegnate con annotazioni, ad esempio)?

P.S Desidero notare che non verranno aggiunte altre classi in fase di esecuzione, tutte le implementazioni IProduct sono note prima della compilazione.

UPD # 1 Grazie per la tua risposta! Ma è possibile creare un file di proprietà generato automaticamente con le istanze IProduct? Intendo dire che è possibile creare uno script di build (ad esempio maven) che genera un file di proprietà o un codice di caricamento? Esistono soluzioni o quadri?

UPD # 2 ho finito con l'utilizzo di Reflections library che fornisce informazioni di runtime, attraverso la scansione classpath in fase di avvio.

risposta

5

Questo è possibile, ma non facilmente. Dovrebbe esaminare tutte le classi nel classpath per vedere se hanno un'annotazione o implementare l'interfaccia IProduct. Vedere How do you find all subclasses of a given class in Java? per le risposte a tale problema.

Lo terrei semplice e ho solo un elenco di classi da caricare, sia nella fabbrica stessa, sia in un file esterno (file delle proprietà, ad esempio).

3
  1. Avere stessa registrare ciascun prodotto, utilizzando un blocco statico come questo:

    class MyProduct1{ 
    
        static{ 
         SomeFactory.register(this.getClass()); 
        } 
        .. 
        .. 
    } 
    
  2. Un file proprietà esterna può tenere traccia di tutti i prodotti.

  3. Il tuo metodo principale può analizzare questo elenco di prodotti e fare un Class.forome ("..").

In questo modo non è necessario codificare alcun prodotto specifico, solo il file delle proprietà continua a cambiare. Ah! sì aggiungere la registrazione di sicurezza sarebbe anche un punto in più.

Nota: sto solo proponendo un'idea, I'vent provato io stesso :)

+6

Come è 'this.getClass()' di andare a lavorare in 'static {}' ... O_O? –

Problemi correlati