web-dev-qa-db-fra.com

Quelle est la vraie différence entre "Bastard Injection" et "Poor Man's Injection"

Dans le livre "Dependency Injection in .Net", je sais que le graphe d'objet doit être créé à l'emplacement racine de Composition de l'application, ce qui me semble tout à fait logique lorsque vous utilisez un conteneur IoC.

Dans toutes les applications que j'ai vues lors d'une tentative d'utilisation de DI, il y a toujours deux constructeurs: l'un avec les dépendances en tant que paramètres et l'autre "default" sans paramètres qui appelle à son tour l'autre "newing" toutes les dépendances, mais, dans le livre susmentionné, cela s'appelle "l'anti-modèle Bastard Injection" et c'est ce que je connaissais sous le nom de "Injection du pauvre homme".

Maintenant, considérant tout cela, je dirais alors que "Poor Man's Injection" n’utiliserait tout simplement pas un conteneur IoC et coderait à la main tout le graphe d’objet à la main sur ladite Composition Root

Donc mes questions sont:

  1. Est-ce que je comprends bien ces concepts ou suis-je complètement en retard?
  2. Si vous devez toujours enregistrer toutes les dépendances dans le conteneur IoC et les coder manuellement dans la même racine de composition, quel est le véritable avantage de l'utilisation d'un conteneur IoC?
  3. Si j'ai mal compris ce qu'est réellement "l'injection du pauvre", quelqu'un pourrait-il clarifier cela?

Merci

55
Sergio Romero

En matière de DI, il y a beaucoup d'utilisation conflictuelle de la terminologie. Le terme Poor Man's DI ne fait pas exception. Pour certaines personnes, cela signifie une chose et pour d'autres, cela signifie quelque chose de différent.

Une des choses que je voulais faire avec le livre était de fournir un langage de motif cohérent pour DI. Quand il s'agissait de tous ces termes avec une utilisation conflictuelle, j'avais deux options: proposer un terme complètement nouveau ou choisir l'usage le plus courant (selon mon jugement subjectif).

En général, j'ai préféré réutiliser la terminologie existante au lieu de créer un langage de motif complètement nouveau (et donc étranger). Cela signifie que dans certains cas (comme le DI de Poor Man), vous pouvez avoir une notion différente de ce que le nom est que la définition donnée dans le livre. Cela arrive souvent avec des modèles de livre.

Au moins, je trouve rassurant que le livre semble avoir bien expliqué son travail en expliquant à la fois PID Man's DI et Bastard Injection, car l’interprétation donnée dans O.P. est exacte.

En ce qui concerne le bénéfice réel d’un conteneur DI, je vous renvoie à cette réponse: Arguments contre l’inversion des conteneurs de contrôle


PS 2018-04-13: Je tiens à souligner qu'il y a des années que je viens de reconnaître que le terme Poor Man's DI fait un travail médiocre (sic!) communiquant l’essence du principe, c’est pourquoi, pendant des années, j’ai je l’ai appelé à la place de Pure DI .

50
Mark Seemann

Quelques notes à la partie 2) de la question.

Si vous devez toujours enregistrer toutes les dépendances dans le conteneur IoC et les coder manuellement dans la même racine de composition, quel est le véritable avantage de l'utilisation d'un conteneur IoC?

  • Si vous avez une arborescence de dépendances (classe qui dépend de dépendances qui dépendent d'autres dépendances, etc.): vous ne pouvez pas faire toutes les "nouvelles" d'une racine de composition, car vous créez de nouvelles instances à chaque "injection de bâtard" constructeur de chaque classe, il existe donc de nombreuses "racines de composition" réparties le long de votre base de code

  • Que vous ayez ou non une arborescence de dépendances, l’utilisation d’un conteneur IoC vous évitera de saisir du code. Imaginez que vous avez 20 classes différentes qui dépendent de la même IDependency. Si vous utilisez un conteneur, vous pouvez fournir une configuration lui permettant de savoir quelle instance utiliser pour IDependency. Cela se fera à un endroit unique et le conteneur veillera à fournir l'instance dans toutes les classes dépendantes.

  • Le conteneur peut également contrôler la durée de vie de l'objet, ce qui offre un autre avantage.

Tout cela, mis à part les autres avantages évidents fournis par DI (testabilité, maintenabilité, découplage de code, extensibilité ...)

4
JotaBe

Nous avons constaté, lors de la refactorisation d'applications héritées et du découplage des dépendances, que les choses ont tendance à être plus faciles lorsque le processus est exécuté en deux étapes. Le processus inclut à la fois les systèmes de conteneur "pauvres" et les systèmes de conteneur IoC formels.

Premièrement: configurez les interfaces et établissez des "médiocres hommes" pour les implémenter. 

  • Cela permet de découpler les dépendances sans la charge supplémentaire (et la courbe d'apprentissage ) D'une configuration IoC formelle.
  • Cela réduit également les interférences avec le code existant. Rien de tel que d'introduire encore un autre ensemble de problèmes à déboguer.
  • Les membres de l'équipe de développement ne sont jamais au même niveau d'expertise ou de compréhension. Cela économise donc beaucoup de temps de mise en œuvre. 
  • Cela permet également de prendre pied pour les cas de test. 
  • Cela établit également des normes pour un système de conteneur IoC formel ultérieurement.
  • Cela peut être mis en œuvre progressivement par beaucoup de gens.

Deuxièmement: chaque système IoC a des avantages et des inconvénients. 

  • Maintenant qu'une norme d'application est établie, une décision éclairée peut être prise pour choisir un système de conteneur IoC. 
  • La mise en œuvre du système IoC devient une tâche consistant à permuter le code "médiocre" avec lenew IoC system.
  • Cela peut être mis en œuvre par étapes et parallèlement à «l'homme pauvre». Il est préférable de diriger cela avec une seule personne.
0
A A