32 votes

Quand ne pas utiliser IoC et DI ?

Je vois beaucoup d'articles disant à quel point IoC et DI sont géniaux et aucun sur les raisons pour lesquelles ils ne sont pas si géniaux car ils peuvent rendre le code plus complexe. Je vois aussi que IoC ne devrait pas être dans la partie centrale de votre code mais plutôt pour les bibliothèques et les plug-ins. Les articles font généralement une petite référence à la façon dont les deux patterns peuvent rendre le code plus compliqué, mais pas grand-chose sur les détails. C'est ma question : où ne devriez-vous pas utiliser ces modèles ?

C'est un beau fil de discussion : Qu'est-ce que l'inversion de contrôle ? . Si vous regardez plus bas, il y a un post sur le vérificateur d'orthographe et un autre post sur le fait que IoC n'est probablement pas une bonne utilisation à cet endroit s'il n'y a qu'un seul vérificateur d'orthographe. En règle générale, IoC ne devrait-il pas être utilisé si je n'ai qu'une seule classe concrète pour l'interface ? C'est-à-dire, j'ai IMyClass. Et ensuite j'ai juste la classe concrète MyClassA qui implémente IMyClass. Pourquoi voudrais-je utiliser IoC à cet endroit ?

Si j'ai MyClassA, MyClassB et MyClassC, qui implémentent chacune IMyClass, ce sont probablement de bons candidats pour IoC, correct ?

Dans le même fil de discussion, quelqu'un sait-il ce que signifie ce message ?

  • Inversion de contrôle = Mariage
  • Conteneur d'IOC = Épouse

32voto

Samuel Carrijo Points 9056

Concernant votre question sur le fait de n'avoir qu'une seule implémentation d'interface. Lorsque vous utilisez IoC, il est toujours utile d'utiliser une interface. Il sera beaucoup plus facile de créer de véritables tests unitaires (qui ne dépendent pas de l'implémentation de l'interface pour fonctionner correctement) en utilisant des mocks pour ces interfaces. L'objectif principal de l'utilisation d'IoC est de rendre le code plus facile à tester. Donc, n'utilisez pas IoC si vous ne voulez pas tester, ou si vous avez déjà un meilleur plan pour tester sans lui.

IMHO, L'augmentation de la complexité de DI et IoC est payée par un code plus facile à tester et moins couplé. Il est plus facile d'isoler les problèmes et d'apporter des changements futurs. Vous pouvez également mieux contrôler son comportement.

Je peux voir quand il ne faut pas utiliser un conteneur IoC (car cela entraîne une surcharge de configuration). Cela se produirait sur de petits projets, où vous pouvez le faire manuellement, au lieu d'utiliser un conteneur. Mais je ne vois pas trop ce que l'on perd à utiliser DI, à moins que vous ne prévoyiez pas de tester votre code...

21voto

Bernard Points 393

Inversion de contrôle = Mariage

Conteneur d'IOC = Épouse

Le mariage est la définition d'un modèle connu - l'épouse est la mise en œuvre de ce modèle ;-)

Bernard.

15voto

Nicholas Blumhardt Points 9208

L'utilisation ou non d'un conteneur IoC n'est pas une décision à prendre au niveau des classes individuelles. Dans tout projet, vous aurez des types qui seront ou non créés par le conteneur.

Le compromis de la complexité est le suivant :

  • Pour un petit nombre de composants, un conteneur IoC ajoute une certaine surcharge.
  • Au fur et à mesure que le nombre de composants d'une application augmente :
    • Sans conteneur IoC, l'ajout de nouveaux composants ou la refactorisation tendent à devenir de plus en plus difficiles.
    • Avec un conteneur IoC, l'ajout de nouveaux composants ou le remaniement reste le même : vous ne devez jamais vous soucier que des dépendances immédiates du composant que vous ajoutez ou modifiez.

Si vous avez déjà été confronté au fait que même une base de code bien conçue et maintenue devient ingérable avec la taille, vous avez connu le problème que les conteneurs IoC résolvent.

11voto

Austin Salonen Points 28057

De le projet Castle :

Pourquoi ne l'utiliserais-je pas ?

Vous ne devez pas utiliser une inversion de si vous n'êtes pas familier avec les concepts et si vous ne réalisez pas les problèmes qu'ils tentent résoudre.

De plus, en fonction de la taille et du complexité du projet, un IoC peut s'avérer superflu. Préférez l'utiliser sur des projets de taille moyenne à grande.

6voto

apenwarr Points 4956

Les plaintes concernant IoC sont faciles à comprendre : IoC transforme quelque chose de simple en quelque chose de compliqué. Disons que vous voulez faire quelque chose à chaque élément d'une liste (en pseudocode) :

for each i in list:
    do_something(i)

L'IoC, essentiellement, consiste à transférer la responsabilité de l'itération de la boucle à quelqu'un d'autre. Ainsi, nous nous retrouvons avec quelque chose comme ça :

ioc = new IocContainer()
ioc.register_callback(do_something)
ioc.go()

Remarquez que même dans cette forme simple, le code est plus long que l'original... et c'est sans compter l'implémentation de IocContainer.

Ensuite, dans sa forme la plus sophistiquée, l'IocContainer peut être initialisé statiquement ou par une fonction Main() statique ou quelque part d'autre caché, et les fonctions register_callback() sont appelées automatiquement en fonction d'un autre code qui itère à travers un fichier XML qui liste toutes vos fonctions do_something() et (parfois) même le contenu des listes à itérer.

Hourra, le fichier XML a rendu votre logiciel plus configurable ! C'est vrai ? Vous pouvez changer ce qui est fait dans votre liste en modifiant un simple fichier texte !

Sauf que, ironiquement, votre code source est maintenant plus longtemps et plus difficile à comprendre, il dépend de toutes sortes de nouvelles bibliothèques, éventuellement boguées (y compris IocContainer et un analyseur XML), et vous l'avez rendu plus difficile à maintenir : Le code XML est plus difficile à comprendre et à modifier que la boucle originale en code source simple (quel que soit le langage dans lequel la boucle est écrite). Vous avez également moins de contrôle sur la manière exacte dont vous voulez effectuer l'itération (triée ou non triée ? en profondeur ou en largeur ?) puisque IocContainer vous enlève cette responsabilité.

Pour des choses comme les plugins, il peut être judicieux d'utiliser IoC, car il est logique pour que l'application principale ait le contrôle du processus d'exécution, et qu'elle puisse simplement demander de l'aide au plugin ici et là. Cela s'appelle "fournir des crochets" et existe depuis bien plus longtemps que la terminologie IoC.

Pour des choses comme les tests unitaires (c'est là que je le vois le plus souvent utilisé), IoC s'avère généralement inutile, parce que vos tests doivent être capables de simuler une grande variété de situations bizarres, et IoC s'y oppose constamment.

L'hypothèse fondamentale de l'IoC est que le chargement de données et le bouclage sont en quelque sorte difficiles et doivent être supprimés ; cette hypothèse n'est tout simplement pas vraie, parce que cela n'a jamais été plus de quelques lignes de toute façon (ou vous pourriez le déplacer vers une fonction distincte), et même si elle a économisé du code, elle réduit votre flexibilité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X