Al di fuori dei quadri di iniezione delle dipendenze, l'iniezione di dipendenza (tramite iniezione del costruttore o iniezione setter) è quasi un gioco a somma zero: si riduce l'accoppiamento tra l'oggetto A e la dipendenza B, ma ora qualsiasi oggetto che necessita di un'istanza di A deve ora anche costruire l'oggetto B.
Hai leggermente ridotto l'accoppiamento tra A e B, ma hai ridotto l'incapsulamento di A e aumentato l'accoppiamento tra A e qualsiasi classe che deve costruire un'istanza di A, accoppiandoli anche alle dipendenze di A.
Quindi l'iniezione di dipendenza (senza un framework) è altrettanto dannosa quanto utile.
Il costo aggiuntivo è spesso facilmente giustificabile, tuttavia: se il codice client sa più come costruire la dipendenza rispetto all'oggetto stesso, allora l'injection dependency riduce realmente l'accoppiamento; ad esempio, uno scanner non sa molto su come ottenere o costruire un flusso di input per analizzare l'input da, o da quale origine il codice client vuole analizzare l'input, quindi l'iniezione del costruttore di un flusso di input è la soluzione più ovvia. p>
Il test è un'altra giustificazione, per poter usare le dipendenze fittizie. Ciò dovrebbe significare l'aggiunta di un costruttore aggiuntivo utilizzato per i test che consente di iniettare le dipendenze: se invece si cambiano i costruttori per richiedere sempre le dipendenze da iniettare, improvvisamente, è necessario conoscere le dipendenze delle dipendenze delle dipendenze per costruire il proprio dipendenze dirette e non è possibile eseguire alcun lavoro.
Può essere utile, ma dovresti sicuramente chiedertelo per ogni dipendenza, il vantaggio del test vale il costo, e ho intenzione di voler prendere in giro questa dipendenza durante il test?
Quando viene aggiunta una struttura di dipendenza dall'iniezione e la costruzione delle dipendenze è delegata non al codice client ma al framework, l'analisi costi / benefici cambia notevolmente.
In un'infrastruttura per l'iniezione delle dipendenze, i compromessi sono leggermente diversi; quello che stai perdendo iniettando una dipendenza è la capacità di sapere facilmente a quale implementazione si sta facendo affidamento, e la responsabilità di decidere su quale dipendenza ti stai affidando a qualche processo di risoluzione automatica (ad esempio se richiediamo un @ Inject'ed Foo , ci deve essere qualcosa che @Provides Foo, e le cui dipendenze iniettate sono disponibili), o ad un file di configurazione di alto livello che prescrive quale provider dovrebbe essere usato per ogni risorsa, o ad alcuni ibridi tra i due (per esempio, ci può essere un processo di risoluzione automatica per le dipendenze che può essere sovrascritto, se necessario, utilizzando un file di configurazione).
Come nell'iniezione del costruttore, penso che il vantaggio di farlo sia, ancora una volta, molto simile al costo di farlo: non devi sapere chi fornisce i dati su cui fai affidamento e, se ci sono sono molteplici potenziali fornitori, non è necessario conoscere l'ordine preferito per verificare la presenza di fornitori, assicurarsi che ogni luogo che ha bisogno di controlli dei dati per tutti i potenziali fornitori, ecc., perché tutto ciò è gestito ad un livello elevato da la piattaforma di distribuzione delle dipendenze.
Anche se personalmente non ho molta esperienza con i framework DI, la mia impressione è che essi forniscano più benefici che costi quando il mal di testa di trovare il fornitore corretto dei dati o del servizio di cui hai bisogno ha un costo maggiore di il mal di testa, quando qualcosa non funziona, di non sapere immediatamente localmente quale codice ha fornito i dati non validi che hanno causato un errore successivo nel codice.
In alcuni casi, altri schemi che oscuravano le dipendenze (es. localizzatori di servizi) erano già stati adottati (e forse hanno anche dimostrato il loro valore) quando i quadri DI apparvero sulla scena, e i quadri DI furono adottati perché offrivano un vantaggio competitivo, come richiedere meno codice boilerplate o potenzialmente fare meno per oscurare il fornitore di dipendenza quando diventa necessario determinare quale fornitore è effettivamente in uso.