En dehors des infrastructures d'injection de dépendance, l'injection de dépendance (via l'injection du constructeur ou l'injection du setter) est presque un jeu à somme nulle: vous diminuez le couplage entre l'objet A et sa dépendance B, mais maintenant tout objet ayant besoin d'une instance de A doit maintenant construit également l'objet B.
Vous avez légèrement réduit le couplage entre A et B, mais réduit l'encapsulation de A et augmenté le couplage entre A et toute classe qui doit construire une instance de A, en les couplant également aux dépendances de A.
Ainsi, l’injection de dépendance (sans cadre) est à la fois nuisible et utile.
Toutefois, le coût supplémentaire est souvent facilement justifiable: si le code client en sait plus sur la manière de construire la dépendance que l’objet lui-même, l’injection de dépendance réduit réellement le couplage; Par exemple, un scanner ne sait pas comment obtenir ou créer un flux d'entrée pour analyser une entrée, ni quelle source le code client veut analyser, de sorte que l'injection de constructeur d'un flux d'entrée est la solution évidente.
Le test est une autre justification, afin de pouvoir utiliser des dépendances factices. Cela devrait impliquer l’ajout d’un constructeur supplémentaire utilisé à des fins de test et permettant d’injecter des dépendances: si vous modifiez vos constructeurs de manière à toujours demander l’injection de dépendances, vous devez connaître les dépendances de ces dépendances afin de construire votre dépendances directes, et vous ne pouvez pas faire le travail.
Cela peut être utile, mais vous devez absolument vous demander pour chaque dépendance, l’avantage des tests en vaut-il la peine, et vais-je vraiment vouloir me moquer de cette dépendance pendant les tests?
Lorsqu'un cadre d'injection de dépendance est ajouté et que la construction des dépendances est déléguée non pas au code client mais au cadre, l'analyse coûts / avantages change considérablement.
Dans un cadre d'injection de dépendance, les compromis sont un peu différents; ce que vous perdez en injectant une dépendance, c’est la capacité de savoir facilement sur quelle implémentation vous vous fiez et de transférer la responsabilité de décider de la dépendance sur laquelle vous comptez compter en un processus de résolution automatisé (par exemple, si nous avons besoin d’un @ Inject'ed Foo , il doit y avoir quelque chose qui @Provides Foo, et dont les dépendances injectées sont disponibles), ou à un fichier de configuration de haut niveau qui spécifie quel fournisseur doit être utilisé pour chaque ressource, ou à un hybride des deux (par exemple, processus de résolution automatisé des dépendances pouvant être remplacées, le cas échéant, à l'aide d'un fichier de configuration).
Comme pour l’injection de constructeur, je pense que l’avantage de le faire finit par avoir un coût très similaire: vous n’avez pas besoin de savoir qui fournit les données sur lesquelles vous comptez et, s’il existe plusieurs potentiels. fournisseurs, vous n’avez pas besoin de connaître l’ordre privilégié pour vérifier la présence des fournisseurs, assurez-vous que chaque emplacement nécessitant des contrôles de données pour tous les fournisseurs potentiels, etc., car tout cela est géré à un niveau élevé par l’injection de dépendance Plate-forme.
Bien que je n’ai pas personnellement beaucoup d’expérience avec les frameworks DI, j’ai l’impression que ceux-ci offrent plus d’avantages que de coûts lorsque trouver le bon fournisseur des données ou du service dont vous avez besoin a un coût supérieur à celui des maux de tête, quand quelque chose échoue, de ne pas savoir immédiatement localement quel code a fourni les données incorrectes qui ont causé une défaillance ultérieure de votre code.
Dans certains cas, d’autres modèles qui masquent les dépendances (par exemple, les localisateurs de service) avaient déjà été adoptés (et ont peut-être également fait leurs preuves) lorsque les cadres d’assurance DI sont entrés en scène, et les cadres d’ID ont été adoptés car ils offraient un avantage concurrentiel, par exemple moins de code passe-partout, ou potentiellement moins pour masquer le fournisseur de dépendance lorsqu'il devient nécessaire de déterminer quel fournisseur est réellement utilisé.