L'inversion de contrôle (IoC) peut être assez déroutante lorsqu'on la rencontre pour la première fois.
- Qu'est-ce que c'est ?
- Quel problème résout-il ?
- Quand est-il approprié de l'utiliser et quand ne l'est-il pas ?
L'inversion de contrôle (IoC) peut être assez déroutante lorsqu'on la rencontre pour la première fois.
Les modèles d'inversion de contrôle (IoC) et d'injection de dépendances (DI) ont pour but de supprimer les dépendances de votre code.
Par exemple, disons que votre application possède un composant éditeur de texte et que vous souhaitez fournir une vérification orthographique. Votre code standard ressemblerait à quelque chose comme ceci :
public class TextEditor {
private SpellChecker checker;
public TextEditor() {
this.checker = new SpellChecker();
}
}
Ce que nous avons fait ici crée une dépendance entre le module TextEditor
et le SpellChecker
. Dans un scénario IoC, nous ferions plutôt quelque chose comme ceci :
public class TextEditor {
private IocSpellChecker checker;
public TextEditor(IocSpellChecker checker) {
this.checker = checker;
}
}
Dans le premier exemple de code, nous instanctions SpellChecker
( this.checker = new SpellChecker();
), ce qui signifie que le TextEditor
dépend directement de la classe SpellChecker
classe.
Dans le deuxième exemple de code, nous créons une abstraction en faisant en sorte que l'élément SpellChecker
classe de dépendance dans TextEditor
La signature du constructeur de la classe (sans initialiser la dépendance dans la classe). Cela nous permet d'appeler la dépendance puis de la passer à la classe TextEditor comme suit :
SpellChecker sc = new SpellChecker(); // dependency
TextEditor textEditor = new TextEditor(sc);
Maintenant, le client qui crée le TextEditor
a le contrôle de la classe SpellChecker
à utiliser parce que nous injectons la dépendance dans l'application TextEditor
signature.
Bon exemple clair. Cependant, supposons qu'au lieu d'exiger que l'interface ISpellChecker soit transmise au constructeur de l'objet, nous l'exposions comme une propriété paramétrable (ou une méthode SetSpellChecker). Cela constituerait-il encore un IoC ?
Chainguy1337 - oui, en effet. L'utilisation de setters comme cela est appelée injection de setter par opposition à l'injection de constructeur (les deux techniques d'injection de dépendance). IoC est un modèle assez générique, mais l'injection de dépendances permet d'obtenir IoC.
Malgré les nombreux votes positifs, cette réponse est incorrecte. Veuillez consulter martinfowler.com/articles/injection.html#InversionOfControl . En particulier, notez la partie disant "L'inversion de contrôle est un terme trop générique, et donc les gens le trouvent confus. En conséquence, après de nombreuses discussions avec divers défenseurs de l'IoC, nous avons opté pour le nom d'injection de dépendances".
L'inversion de contrôle est ce que vous obtenez lorsque votre programme fait des callbacks, par exemple comme un programme gui.
Par exemple, dans un menu de la vieille école, vous pourriez avoir :
print "enter your name"
read name
print "enter your address"
read address
etc...
store in database
contrôlant ainsi le flux de l'interaction avec l'utilisateur.
Dans un programme GUI ou autre, on dira plutôt :
when the user types in field a, store it in NAME
when the user types in field b, store it in ADDRESS
when the user clicks the save button, call StoreInDatabase
Le contrôle est donc maintenant inversé... au lieu que l'ordinateur accepte les entrées de l'utilisateur dans un ordre fixe, l'utilisateur contrôle l'ordre dans lequel les données sont saisies et le moment où elles sont enregistrées dans la base de données.
En gros, tout ce qui est avec une boucle d'événement, des callbacks ou des déclencheurs d'exécution entre dans cette catégorie.
Ne notez pas ce type. Techniquement, il a raison. martinfowler.com/bliki/InversionOfControl.html IoC est un principe très général. Le flux de contrôle est "inversé" par l'injection de dépendances, car vous avez effectivement délégué les dépendances à un système externe (par exemple, un conteneur IoC).
D'accord avec le commentaire de Schneider. 5 votes négatifs ? C'est à n'y rien comprendre, puisque c'est la seule réponse qui soit vraiment correcte. Notez le début : comme un programme gui.' L'injection de dépendances n'est que la réalisation la plus courante de l'IoC.
En effet, c'est l'une des rares correct anwsers ! Les gars, IoC est pas fondamentalement sur les dépendances. Pas du tout.
Qu'est-ce que l'inversion de contrôle ?
Si vous suivez ces deux simples étapes, vous avez effectué une inversion de contrôle :
Il existe plusieurs techniques possibles pour chacune de ces étapes, en fonction de la technologie/du langage que vous utilisez pour votre mise en œuvre.
--
Le site inversion partie de l'inversion de contrôle (IoC) est la chose la plus déroutante ; parce que inversion est le terme relatif. La meilleure façon de comprendre IoC est d'oublier ce mot !
--
Exemples
Comment vous dites Interfaces. Le client du composant (partie "quand faire") car "quand" n'a pas de sens lorsque nous utilisons des interfaces (ex : injection de dépendance), nous l'abstrayons simplement et donnons au client la flexibilité d'ajouter une implémentation mais il n'y a pas de "quand" impliqué ici. Je suis d'accord avec le "quand" dans le cas de la levée d'événements du traitement des événements.
Par "composant client", j'entends l'utilisateur/client de l'interface. Le client sait "quand" déclencher la partie "quoi faire", que l'intention soit d'étendre la fonctionnalité ou non.
Jetez un coup d'œil à ce merveilleux article de Martin Fowler. Il montre comment les interfaces constituent la partie fondamentale de l'inversion du contrôle : martinfowler.com/articles/injection.html#InversionOfControl
Avant d'utiliser l'inversion de contrôle, vous devez être bien conscient du fait qu'elle a ses avantages et ses inconvénients et vous devez savoir pourquoi vous l'utilisez si vous le faites.
Pour :
Cons :
Personnellement, je vois les points forts de l'IoC et je les apprécie vraiment, mais j'ai tendance à éviter l'IoC autant que possible parce qu'il transforme votre logiciel en une collection de classes qui ne constituent plus un "vrai" programme mais juste quelque chose qui doit être assemblé par des métadonnées de configuration ou d'annotation XML et qui tomberait (et tombe) en morceaux sans lui.
La première affirmation est incorrecte. Idéalement, il ne devrait y avoir qu'une seule utilisation du conteneur IOC dans votre code, et c'est votre méthode principale. Tout le reste devrait descendre en cascade à partir de là
Je pense que ce qu'il veut dire, c'est que vous ne pouvez pas simplement lire : myService.DoSomething() et aller à la définition de DoSomething, parce qu'avec IoC, myService est juste une interface, et l'implémentation réelle vous est inconnue, à moins que vous alliez la chercher dans les fichiers de configuration xml ou dans la méthode principale où votre ioc est configuré.
C'est là que Resharper intervient - "cliquer pour aller à l'implémentation" contre l'interface. Éviter IoC (ou plus précisément DI dans votre exemple) signifie probablement aussi que vous ne testez pas correctement
Article de Wikipedia . Pour moi, l'inversion de contrôle consiste à transformer votre code écrit de manière séquentielle et à le transformer en une structure de délégation. Au lieu que votre programme contrôle explicitement tout, votre programme met en place une classe ou une bibliothèque avec certaines fonctions à appeler lorsque certaines choses se produisent.
Il résout la duplication du code. Par exemple, dans le passé, vous deviez écrire manuellement votre propre boucle d'événements, en interrogeant les bibliothèques système pour les nouveaux événements. Aujourd'hui, dans la plupart des API modernes, il vous suffit d'indiquer aux bibliothèques système les événements qui vous intéressent, et elles vous informeront lorsqu'ils se produiront.
L'inversion de contrôle est un moyen pratique de réduire la duplication du code. Si vous vous retrouvez à copier une méthode entière et à ne modifier qu'une petite partie du code, vous pouvez envisager de l'aborder avec l'inversion de contrôle. L'inversion de contrôle est facilitée dans de nombreux langages par le concept de délégués, d'interfaces ou même de pointeurs de fonction bruts.
Il n'est pas approprié de l'utiliser dans tous les cas, car le flux d'un programme peut être plus difficile à suivre lorsqu'il est écrit de cette façon. C'est une façon utile de concevoir des méthodes lors de l'écriture d'une bibliothèque qui sera réutilisée, mais elle doit être utilisée avec parcimonie dans le cœur de votre propre programme, à moins qu'elle ne résolve vraiment un problème de duplication de code.
Je trouve que cet article de Wikipedia est très confus et a besoin d'être corrigé. Allez voir la page de discussion pour rire un peu.
Écrire votre propre boucle d'événement pourrait encore être une inversion de contrôle, si cette boucle d'événement prend la place d'un framework et que le reste du code utilise le principe IoC, vous venez d'écrire votre propre framework. En fait, ce n'est pas une mauvaise chose, cela augmente la lisibilité au prix d'un peu plus de codage (ce qui n'est pas toujours approprié non plus).
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.
352 votes
Le problème de la plupart de ces réponses est la terminologie utilisée. Qu'est-ce qu'un conteneur ? Une inversion ? Dépendance ? Expliquez-le en termes simples, sans les grands mots.
15 votes
Voir aussi sur Programmers.SE : Pourquoi l'inversion du contrôle s'appelle-t-elle ainsi ?
12 votes
Il s'agit de l'injection de dépendances (DI) - voir la description de Martin Fowlers ici : martinfowler.com/articles/injection.html#InversionOfControl
0 votes
C'est un adjectif, pas un nom, ce n'est pas une chose, c'est une description d'un changement apporté au code, où le contrôle du flux est dans le délégué, pas le conteneur.
0 votes
La meilleure façon de comprendre IOC est d'entendre Martin Fowler et Oncle BOB... il suffit de taper IOC avec les noms mentionnés.
0 votes
Inversion de contrôle = injection de dépendances (état) + injection de continuité (fonction) + injection de threads . Plus de détails ici : dzone.com/articles/inversion-of-coupling-control