2013-11-01 7 views
5

Ho una classe con un costruttore in cui tutti gli argomenti vengono iniettati da GUICE.Costruttore Java con campi iniettati da Guice insieme a campi non iniettati

Public class Order { 

    private final ClassOne classOneObj; 
    private final ClassTwo classTwoObj; 

    @Inject 
    public order(ClassOne classOneObj, ClassTwo classTwoObj){ 
    this.classOneObj = classOneObj; 
    this.classTwoObj = classTwoObj; 
    } 
} 

Ora, voglio aggiungere un'altra variabile di campo (ad esempio, stato int) che non può essere iniettata.

È buona norma creare un oggetto in primo luogo con tutti i parametri iniettati e quindi impostare il nuovo campo che non può essere iniettato con metodo setter?

mi si avvicinò con un altro approccio in cui ho creato una classe di fabbrica come il seguente: Quindi la nuova classe Order sarà simile

public class Order { 

    int status 
    private final ClassOne classOneObj; 
    private final ClassTwo classTwoObj; 


    public order(int status, ClassOne classOneObj, ClassTwo classTwoObj){ 
    this.status = status 
    this.classOneObj = classOneObj; 
    this.classTwoObj = classTwoObj; 
    } 

    //getter methods for all these member variables 
} 

Ora per creare l'oggetto dell'ordine lo farò

public class OrderFactory { 

    private final ClassOne classOneObj; 
    private final ClassTwo classTwoObj; 

    @Inject 
    public order(ClassOne classOneObj, ClassTwo classTwoObj){ 
    this.classOneObj = classOneObj; 
    this.classTwoObj = classTwoObj; 
    } 

    //getter methods for all the above variables 

    public ClassOne getclassOneObj(){ 
      return classOneObj; 
    } 
    .... 

    public Order createOrder(int status) { 
     return new Order(status, classOneObj, classTwoObj); 
    } 
} 

prima creare un oggetto OrderFactory e quindi utilizzare il metodo "createOrder". Creerò l'oggetto Order.

Sto finendo con la scrittura di codice standard. Non sono sicuro se questa è una buona pratica. Qualcuno può suggerire questo se questo approccio è corretto o c'è un approccio migliore per questo problema?

ho letto in Google Guice e ha trovato c'è una caratteristica @Assisted per l'iniezione assistita per tali casi. Ma ho trovato questo complesso e non riuscivo a convincermi se dovessi andare con quello nel mio caso.

Grazie in anticipo per qualsiasi suggerimento o guida.

+0

Facendo eco iluxa, il tuo approccio manuale per fabbriche va bene, anche se è possibile far funzionare l'iniezione assistita in un modo molto più breve. L'unica cosa che cambierei nella tua iniezione manuale è iniettare un 'Provder ' e 'Provider ', invece, se vuoi creare molti Ordini diversi con lo stesso OrderFactory. Altrimenti, sembra fantastico. –

risposta

-1

sei tipicamente intenzione di iniettare cose che prendono una certa quantità di sforzo per costruire. Se si sta solo iniettando un campo int, starai meglio chiamando un metodo setter sull'oggetto (che ha alcune delle sue più complesse dipendenze iniettate). Inoltre, se un campo cambia frequentemente, come implicito in un campo chiamato "status", allora non è nemmeno un buon candidato per l'iniezione.

+1

Si prega di evitare setter quando possibile. Se c'è qualche possibilità di mantenere l'oggetto immutabile e tutti i suoi campi 'final', fallo. – iluxa

+0

+1 a iluxa. Gli oggetti immutabili hanno [molti vantaggi] (http://stackoverflow.com/a/214718/1426891).Siamo tutti d'accordo sul fatto che l'iniezione di 'status' è una cattiva idea, ma la domanda dell'OP riguardava il fatto che l'iniezione coesistesse con gli argomenti del costruttore _non-injer_, per i quali esistono molti casi d'uso validi. –

+0

Sì, lavorare per Google ti insegna una o due cose su Guice non ... :-) – iluxa

4

L'approccio di fabbrica è eccellente. Per favore non usare i setter: se il campo può essere reso immutabile, dovrebbe essere immutabile, anche se non lo rende "conveniente" per creare un'istanza.

Un altro approccio si può prendere è Assisted Injection, che risolve questo problema esatto. Con questo, si definisce solo l'interfaccia di fabbrica, e la sua attuazione è magicamente dato a voi da Guice: codice

class Order { 
    interface Factory { 
    Order create(Status status); 
    } 

    @AssistedInject Order(
     ClassOne one, 
     ClassTwo two, 
     @Assisted Status status) { 
    } 
} 

Modulo:

bind(Order.Factory.class).toProvider(
    FactoryProvider.newFactory(Order.Factory.class, Order.class)); 

Poi i clienti iniettare Factory e utilizzarlo proprio come fanno nel tuo esempio.

Problemi correlati