Comment l'injection de dépendance augmente-t-elle le couplage?

32

Sur la page Wikipedia sur l' injection de dépendance, la section des inconvénients nous dit ceci:

L'injection de dépendance augmente le couplage en obligeant l'utilisateur d'un sous-système à répondre aux besoins de ce sous-système.

avec un lien vers un article contre l'injection de dépendance .

L'injection de dépendance fait qu'une classe utilise l'interface au lieu de l'implémentation concrète. Cela devrait entraîner une diminution du couplage , non?

Qu'est-ce que je rate? Comment le lien de dépendance augmente-t-il le couplage entre les classes?

BЈовић
la source
2
Je ne sais pas qui a écrit cette liste d'inconvénients, mais je la prendrais avec un grain de sel. Par exemple, j'ai constaté que DI réduisait la taille d'une base de code de 2/3 en éliminant une tonne de code de configuration redondant.
Rob
@ Roby J'ai principalement utilisé factory pour injecter la dépendance, et mon expérience est qu'il augmente la taille du code, mais simplifie les tests.
BЈовић
Essayez d’utiliser une alternative telle que Registry ou Context Passing;) Ou alors du code qui instancie simplement des objets puis extrait leurs propriétés de config. Principalement, je parle de la différence entre maintenant et 15 ans.
Rob
Connexe: stackoverflow.com/a/9503612/264697 . La réponse de Mark Seemann explique comment le couplage global est réduit à l'aide de Dependency Injection.
Steven

Réponses:

42

Alors, qu'est-ce qui me manque?

Dépendance L'injection diminue le couplage entre une classe et sa dépendance. Mais il augmente le couplage entre une classe et son consommateur (puisque le consommateur a besoin de plus d’informations pour la créer) et la dépendance et son consommateur (puisque le consommateur a besoin de connaître la dépendance à utiliser).

Très souvent, c'est un bon compromis. La classe ne devrait pas savoir les détails au sujet de ses dépendances au - delà d' une interface, et il devrait être la responsabilité de l'application de lier des bits spécifiques de code ensemble.

Telastyn
la source
À droite, le couplage est diminué dans un sens et augmenté dans un autre.
Paul Draper
Mais le consommateur ne le crée pas; c'est plutôt le point.
Casey
@ emodendroket - Hein? Inversion of Control permet au consommateur de ne pas le créer. Dependency Injection est orthogonal à cela.
Telastyn
Eh bien, vous faites une distinction que je ne connais pas bien, car les termes sont généralement utilisés de manière interchangeable.
Casey
22

Supposons que vous ayez un sous S- système qui dépend d'une connexion à une base de données D. Sans injection de dépendance, il existe un lien relativement étroit entre Set D, car il Sfaut savoir comment l’utiliser Det le créer. Le reste du système peut toutefois ignorer parfaitement cette dépendance entre Set D.

Avec l'injection de dépendance, le couplage entre Set Ddevient plus lâche, car vous supprimez de Sla connaissance comment créer un fichier D. Sjuste besoin de savoir comment l'utiliser. Le couplage global accru provient du fait que d' autres parties du système doivent maintenant savoir Det éventuellement en créer un. L'ampleur de cette augmentation du couplage dépend de la manière dont la dépendance Dest injectée dans S:

  • Avec l' injection de constructeur, le créateur a Sbesoin d'une dépendance Det éventuellement du savoir-faire pour en créer une.
  • Avec l' injection au niveau de la méthode , chaque appelant d'une méthode Spar laquelle un Dest injecté a besoin d'une dépendance Det éventuellement du savoir-faire pour en créer une.

Dans les deux cas, le nombre de classes dépendantes Daugmente et le savoir-faire pour créer une image Dimmobile doit être présent quelque part dans le système. Cela crée une augmentation globale du couplage.

Bart van Ingen Schenau
la source
Ok, cela a du sens pour l'injection de constructeur et de setter. Mais si l’on utilise un modèle d’usine ou de stratégie, la création y est déplacée et la classe n’utilise que l’objet injecté. Ou n'est-ce pas une injection de dépendance (inversion du contrôle uniquement)?
BЈовић
Même avec l'injection en usine, le créateur de Sdoit fournir une usine à D, ce qui signifie qu'il doit savoir qui Sutilise D(ou au moins une interface de celle-ci).
Idan Arye
7

Je ne suis pas du tout d'accord pour dire que cela augmente le couplage.

Sans injection de dépendance, vous avez un couplage étroit entre un sous-système et la mise en œuvre concrète de la dépendance.

Avec l'injection de dépendance, vous avez découplé le sous-système de la mise en œuvre de la dépendance.

Argumenter sur le fait qu'il augmente le couplage entre le consommateur et ce sous-système est TRÈS discutable car cela implique que le consommateur est maintenant étroitement couplé à la dépendance requise par le sous-système. Tout ce que cela signifie, c'est que vous écrivez un code étroitement couplé qui couple votre consommateur à la dépendance. Idéalement ALL votre code est découplé.

Injection de constructeur:

La résolution des dépendances est gérée par un conteneur d'injection de dépendances ou une usine. Le consommateur peut obtenir une implémentation concrète du sous-système à partir du conteneur d'injection de dépendance ou d'une usine.

Le consommateur n'a pas besoin de savoir à quoi ressemble le constructeur du sous-système. Il n'y a pas de couplage avec la dépendance du sous-système.

Méthode d'injection:

Identique à l'injection de constructeur, sauf que le consommateur doit maintenant obtenir une instance concrète de la dépendance du conteneur ou de l'usine (ou même l'injecter méthode / constructeur) et l'injecter dans la méthode. Encore une fois, le consommateur n'est pas associé à une implémentation concrète de la dépendance.

TL; DR Le pire cas d'injection de dépendance dans un sous-système est que le couplage est décalé vers le code consommateur. IL N'Y A AUCUNE AUGMENTATION GLOBALE DU COUPLAGE.

Le meilleur des cas est que tous les systèmes sont maintenant faiblement couplés et que l'injection de dépendance est contrôlée par le biais de conteneurs ou d'usines d'injection de dépendance.

faucon
la source