Costruttore che contiene dipendenze di classe

0

È consigliabile inizializzare le dipendenze delle classi in un costruttore o se una classe deve essere inizializzata nel metodo in cui viene utilizzata. Diciamo che abbiamo la seguente situazione, e PriceCalcService è usato solo in un paio di metodi. L'ordine prende anche altri parametri e imposta il suo stato.

public class ShippingService() { .......... }

public class Order() {
    public string SomeOrderProperty;
    private PriceCalcService priceCalcService;

    public Order(string someOrderproperty) {
         priceCalcService= new PriceCalcService();
         SomeOrderProperty = someOrderProperty;
    }

    public void Method1() {
         PriceCalcService.MethodX();
    }
    .......
}

O il PriceCalcService dovrebbe essere inizializzato solo nei metodi che lo usano?

public class PriceCalcService() { .......... }  

public class Order() {

    public string SomeOrderProperty;
    public Order(string someOrderproperty) {
         SomeOrderProperty = someOrderproperty;
    }

    public void Method1() {
         new PriceCalcService().MethodX();
    }
    .......
}

Primo esempio: Vantaggio: possiamo vedere le dipendenze                Svantaggio: istanziamo una classe anche se non viene utilizzata. Quale metodo dovrei scegliere?

    
posta Icebraker 05.01.2017 - 13:02
fonte

3 risposte

7

Is it a best practice to initialize class dependencies in a constructor or should a class be initialized in the method where it is used

No. Nemmeno le buone pratiche. La buona pratica è:

  1. fa riferimento a tali dipendenze tramite interfacce,
  2. Inietta le dipendenze tramite il costruttore

Quindi il codice potrebbe essere simile a:

public class Order() {
    private IShippingService shippingService;

    public Order(IShippingService shippingService) {
         this.shippingService = shippingService;
    }

    public void Method1() {
        shippingService.MethodX();
    }
    .......
}
    
risposta data 05.01.2017 - 13:06
fonte
3

Consenti al POJO di essere POJO .

La responsabilità di un oggetto ordine è di conservare le informazioni di un ordine.

public class Order() {

    //let the properties of the pojo be private
    private String orderDescription;

    public Order(String orderDescription) {
       this.orderDescription = orderDescription;
    }

    //getters/setters
}

Consenti al servizio di essere il servizio.

Il servizio è responsabile del contenimento dei metodi che prendono un ordine e operano su di essi.

public class ShippingService() { 
  public void processShipping(Order order){
    //write the body of the method that takes the order and do the shipping.
  }
}

In modo astratto, hai un oggetto che è un POJO. Quindi hai un servizio che contiene le modalità di lavoro con quell'oggetto. In questo modo puoi sviluppare il tuo oggetto - aggiungendo nuove proprietà - e il servizio - aggiungendo nuove funzionalità - in modo separato.

    
risposta data 05.01.2017 - 13:58
fonte
1

In generale, se stiamo parlando di un'applicazione aziendale e desideri supportare il test automatico dell'unità, segui queste regole:

  1. Le iniezioni dovrebbero essere iniettate.
  2. Altre inizializzazioni dovrebbero essere eseguite al di fuori del costruttore, appena prima che sia effettivamente necessario ( "pigro" )

Ciò consente a un framework di test delle unità di isolare la logica del metodo dalla logica del costruttore, fornendo al contempo interfacce fittizie via DI.

D'altro canto, se stiamo parlando di un'applicazione in tempo reale come un videogioco, dovresti probabilmente eseguire tutta l'inizializzazione nel costruttore in modo che le prestazioni del codice siano prevedibili.

    
risposta data 06.01.2017 - 01:21
fonte

Leggi altre domande sui tag