In che modo l'iniezione di dipendenza aumenta l'accoppiamento?


32

Nella pagina Wikipedia sull'iniezione delle dipendenze, la sezione degli svantaggi ci dice questo:

L'iniezione di dipendenza aumenta l'accoppiamento richiedendo all'utente di un sottosistema di provvedere alle esigenze di quel sottosistema.

con un collegamento a un articolo contro l'iniezione di dipendenza .

L'iniezione di dipendenza fa sì che una classe usi l'interfaccia anziché l'implementazione concreta. Ciò dovrebbe comportare una riduzione dell'accoppiamento , no?

Cosa mi sto perdendo? In che modo l'iniezione di dipendenza aumenta l'accoppiamento tra le classi?


2
Non sono sicuro di chi abbia scritto quell'elenco di svantaggi, ma lo prenderei con un granello di sale. Ad esempio, ho visto DI ridurre le dimensioni di una base di codice di 2/3 eliminando una tonnellata di codice di installazione ridondante.
Rob

@RobY Ho usato principalmente factory per iniettare la dipendenza, e la mia esperienza è che aumenta la dimensione del codice, ma semplifica i test.
BЈовић,

Prova a utilizzare un'alternativa come Registry o Context Passing;) Altrimenti codice che crea un'istanza degli oggetti e quindi estrae le loro proprietà dalla configurazione. Principalmente, sto parlando della differenza tra ora e 15 anni fa.
Rob,

Correlato: stackoverflow.com/a/9503612/264697 . La risposta di Mark Seemann spiega come viene ridotto l'accoppiamento complessivo mediante l'iniezione delle dipendenze.
Steven,

Risposte:


42

Quindi, cosa mi sto perdendo?

L'iniezione di dipendenza riduce l'accoppiamento tra una classe e la sua dipendenza. Ma aumenta l'accoppiamento tra una classe e il suo consumatore (poiché il consumatore ha bisogno di più informazioni per crearla) e la dipendenza e il suo consumatore (poiché il consumatore deve conoscere la dipendenza da usare).

Molto spesso, questo è un buon compromesso. La classe non dovrebbe conoscere i dettagli delle sue dipendenze oltre un'interfaccia e dovrebbe essere responsabilità dell'applicazione legare insieme specifici bit di codice.


Bene, l'accoppiamento è diminuito in un modo e aumentato in un altro.
Paul Draper,

Ma il consumatore non lo crea; questo è piuttosto il punto.
Casey,

@emodendroket - Eh? Inversion of Control consente al consumatore di non crearlo. L'iniezione di dipendenza è ortogonale a quella.
Telastyn,

Bene, stai facendo una distinzione con cui non ho familiarità, dato che di solito i termini sono usati in modo intercambiabile.
Casey,

22

Supponiamo di avere un sottosistema Sche dipende da una connessione al database D. Senza iniezione di dipendenza, esiste un accoppiamento relativamente stretto tra Se D, poiché Sdeve sapere sia come utilizzarlo Dsia come crearlo. Il resto del sistema, tuttavia, può essere beatamente inconsapevole di questa dipendenza tra Se D.

Con l'iniezione di dipendenza, l'accoppiamento tra Se Ddiventa più libero, perché si rimuove dalla Sconoscenza come creare un D. Sdeve solo sapere come usarlo. Il maggiore accoppiamento complessivo deriva dal fatto che altre parti del sistema devono ora conoscere De possibilmente come crearne uno. L'entità di questo aumento nell'accoppiamento dipende da come Dviene iniettata la dipendenza da S:

  • Con l' iniezione del costruttore, il creatore di ha Sbisogno di una dipendenza De possibilmente della conoscenza su come crearne una.
  • Con l' iniezione a livello di metodo , ogni chiamante di un metodo Sattraverso il quale Dviene iniettato ha bisogno di una dipendenza De possibilmente delle conoscenze su come crearne uno.

In entrambi i casi, il numero di classi che dipende dagli Daumenti e la conoscenza di come creare un oggetto Ddeve essere ancora presente da qualche parte nel sistema. Ciò crea un aumento complessivo dell'accoppiamento.


Ok, ha senso per l'iniezione del costruttore e del setter. Ma se si utilizza il modello di fabbrica o di strategia, la creazione viene spostata lì e la classe utilizza solo l'oggetto iniettato. Oppure non è un'iniezione di dipendenza (solo inversione di controllo)?
BЈовић,

Anche con l'iniezione di fabbrica, il creatore di Sdeve fornire una fabbrica di D, il che significa che deve sapere che Sutilizza D(o almeno una sua interfaccia).
Idan Arye,

7

Non sono assolutamente d'accordo sul fatto che aumenti l'accoppiamento.

Senza iniezione di dipendenza si ha uno stretto accoppiamento tra un sottosistema e l'implementazione concreta della dipendenza.

Con l'iniezione delle dipendenze hai disaccoppiato il sottosistema dall'implementazione della dipendenza.

L'argomentazione secondo cui aumenta l'accoppiamento tra il consumatore e questo sottosistema è MOLTO discutibile in quanto implica che il consumatore è ora strettamente accoppiato alla dipendenza richiesta dal sottosistema. Tutto ciò significa che stai scrivendo un codice strettamente accoppiato che accoppia il tuo consumatore alla dipendenza. Idealmente TUTTO il tuo codice è disaccoppiato.

Iniezione costruttore:

La risoluzione delle dipendenze viene gestita da un contenitore di iniezione delle dipendenze o da una fabbrica. Il consumatore può ottenere un'implementazione concreta del sottosistema dal contenitore di iniezione della dipendenza o da una fabbrica.

Il consumatore non ha bisogno di sapere come sia il costruttore del sottosistema. Non esiste accoppiamento alla dipendenza del sottosistema.

Iniezione di metodo:

Come per l'iniezione del costruttore, tranne per il fatto che ora il consumatore ha bisogno di ottenere un'istanza concreta della dipendenza dal contenitore o dalla fabbrica (o addirittura far iniettare il metodo / costruttore) e iniettarlo nel metodo. Ancora una volta, il consumatore non è accoppiato a un'implementazione concreta della dipendenza.

TL; DR Il caso peggiore per l'iniezione di dipendenza in un sottosistema è che l'accoppiamento viene spostato sul codice del consumatore. NON CI È AUMENTO GENERALE DELL'ACCOPPIAMENTO.

Il caso migliore è che ora tutti i sistemi sono liberamente accoppiati e l'iniezione di dipendenza è controllata attraverso contenitori o fabbriche di iniezione di dipendenza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.