L'iniezione di dipendenza appartiene a costruttori, setter o altri metodi?

0

Posso scrivere codice come:

var dependency = "Hello!"
var something = new Something(dependency);
something.DoStuffWithDependency();

Oppure potrei scrivere come:

var dependency = "Hello!"
var something = new Something();
something.DoStuff(dependency);

Dove il primo esempio prende la dipendenza dal costruttore e lo usa in qualche metodo.

Perché è una dipendenza, appartiene al costruttore? O dovrebbe essere iniettato nel metodo?

    
posta Dudemanword 04.11.2016 - 16:20
fonte

6 risposte

6

Entrambi gli esempi sono cattivi. Non creare un'istanza di una classe per richiamare un singolo metodo e quindi abbandonare l'istanza.

In altre parole: dipende. La domanda dovrebbe essere risolta concettualmente in base al tuo scenario attuale , non tecnicamente basato su uno scenario astratto.

Se il tuo Qualcosa ha un sacco di metodi e molti di loro agiscono sulla stessa dipendenza e una singola istanza avrà diversi di questi metodi chiamati, allora la dipendenza è migliore come un campo.

Se il tuo Something ha diversi metodi e dipendenze multiple, ognuna delle quali viene utilizzata solo da un singolo metodo, allora è meglio passarla nel metodo.

Ma devi anche considerare se queste dipendenze sono in realtà disponibili facilmente nel punto in cui l'oggetto è costruito, o nel punto in cui viene chiamato il metodo. Ciò potrebbe anche influenzare il design.

    
risposta data 04.11.2016 - 16:31
fonte
4

Penso che dovresti mettere la dipendenza nel costruttore se vuoi usarlo per più scopi rispetto al metodo .DoStuff. In questo modo, la dipendenza è riutilizzabile.

Se è strettamente per il metodo .DoStuff, lo inserirò nel metodo solo una volta.

Questo è il modo in cui mi è stato insegnato in generale come studente

    
risposta data 04.11.2016 - 16:26
fonte
2

La parte di dipendenza della classe o il richiamo del metodo?

Se la dipendenza fa parte dell'identità della classe, o dei dati che deve essere trasportata, passala al costruttore.

Se la dipendenza viene utilizzata solo nel metodo e da nessun'altra parte, passala nel metodo.

In altre parole: nel contesto della dichiarazione di classe, si utilizza tale dipendenza ovunque al di fuori dell'ambito del metodo diverso dalla dichiarazione e dall'inizializzazione di variabili?

    
risposta data 04.11.2016 - 16:58
fonte
2

In questo esempio, non ha molta importanza. Non c'è niente di sbagliato in un'istanza stateless, quindi il costruttore vuoto va bene. Non c'è niente di sbagliato con lo stato di mantenimento da utilizzare con il metodo.

Tuttavia ci sono delle conseguenze. È difficile vederli qui perché la costruzione e l'uso sono stati mescolati insieme.

Supponiamo che tu voglia chiamare doStuff() da un luogo che non ha alcuna conoscenza della tua dipendenza. Conosce solo Something . Ora devi rendere questo posto consapevole della dipendenza da chiamare il tuo metodo.

Ora, se questo nuovo posto è già a conoscenza della dipendenza, e in effetti se ha qualche altro da chiamare, e non c'è bisogno di ricordarlo, passarlo attraverso un metodo che pende da un'istanza senza stato va bene .

Alcuni odiano l'idea di un'istanza senza stato quindi preferiscono rendere doStuff() statico. Questo funziona ma è limitante, poiché ora non puoi passare l'istanza senza stato. Qualsiasi cosa che richiama una doStuff() statica chiama direttamente un'implementazione concreta.

L'istanza stateless non statica lo evita, permettendoti di passare qualsiasi versione di Something.doStuff() che ti piace. Puoi trattare il tuo metodo come una funzione. In effetti questa linea di pensiero può portarci a interfacce di metodo singole e lambda.

    
risposta data 04.11.2016 - 16:42
fonte
1

Suppongo che tu abbia impostato la dipendenza per delegare alcune funzioni o un'alternativa all'ereditarietà per aggiungere o modificare la funzionalità di una classe senza estenderla.

Uno:

Nella maggior parte dei casi simili si inietta la dipendenza in modo che possa essere utilizzata in più di una posizione, quindi ha senso averla come parte dello stato, cioè, diversi metodi pubblici o privati potrebbero delegare alcune funzioni alla dipendenza hai iniettato. È possibile iniettare la dipendenza nel costruttore o con getter.

Inoltre, puoi iniettare più di una dipendenza per delegare diverse funzioni a loro:

Thing t = new Thing(method, collation, locale);
t.convert(someData);
t.validate(someData);
t.format(someData);

o

Thing t = new Thing();
t.setMethod(method);
t.setCollation(collation);
t.setLocale(locale);
t.convert(someData);
t.validate(someData);
t.format(someData);

due:

Se passi solo un oggetto a un metodo da utilizzare in quel metodo e cioè, non è veramente considerato l'iniezione di una dipendenza. Passa un parametro a un metodo che sembra essere solo un tipo non primitivo, anche se chiami alcuni dei metodi di quell'oggetto. Una volta che doStuff(Dependency d) è stato eseguito, nessun riferimento a d è contenuto nello stato della classe, quindi nulla è stato "iniettato" nella classe.

È così:

public method PrintPersonDetails(Person p){
      p.printDetails();
      // when it ends, no reference to p stays inside this class
      // so you injected nothing
}

Quindi, per rispondere alla tua domanda , le dipendenze che vuoi formare sono dello stato degli oggetti e a cui l'oggetto delegherà alcune funzioni, cambiando così il suo comportamento senza dover estendere la classe , può essere passata nel contructor o tramite getters .

L'altra cosa non è l'iniezione di dipendenza.

    
risposta data 04.11.2016 - 19:38
fonte
0

La mia regola è: "Dovresti aspettarti che il metodo restituisca lo stesso risultato se lo chiami con gli stessi parametri"

. se la dipendenza ha uno stato che modifica il risultato del metodo, impostalo come parametro del metodo. Se la dipendenza configura semplicemente il comportamento della classe, passala nel costruttore.

Ma. Io preferisco il costruttore. Quindi, se ad esempio ho un servizio IWeather, ovviamente il tempo può cambiare, quindi due chiamate a un metodo: WeatherIn (città) possono restituire risultati diversi.

Piuttosto che il brutto WeatherIn (città, weatherService) vorrei andare a WeatherIn (città, data / ora) per raggiungere l'apolidia e mantenere il parametro di costruzione

    
risposta data 04.11.2016 - 19:45
fonte

Leggi altre domande sui tag