Les mots invert
ou control
ne sont pas utilisés du tout pour définir Inversion of Control dans les définitions que j'ai vues.
Définitions
Wikipédia
inversion of control (IoC) est une technique de programmation, exprimée ici en termes de programmation orientée objet, dans laquelle le couplage d'objet est lié au moment de l'exécution par un objet assembleur et n'est généralement pas connu au moment de la compilation à l'aide d'une analyse statique. ~ http://en.wikipedia.org/wiki/Inversion_of_control
Martin Fowler
L'inversion de contrôle est un modèle courant dans la communauté Java qui aide à câbler des conteneurs légers ou à assembler des composants de différents projets dans une application cohérente. ~ basé sur http://www.martinfowler.com/articles/injection.html (reformulé)
Alors, pourquoi Inversion of Control est-il appelé Inversion of Control? Quel contrôle est inversé et par quoi? Existe-t-il un moyen de définir l'inversion de contrôle à l'aide de la terminologie: inverser et contrôler ?
la source
Réponses:
Supposons que vous ayez une sorte de classe "référentiel" et que ce dernier soit responsable de la gestion des données depuis une source de données.
Le référentiel pourrait établir une connexion à la source de données par lui-même. Mais que se passe-t-il si cela vous permettait de passer une connexion à la source de données via le constructeur du référentiel?
En autorisant l'appelant à établir la connexion, vous avez dissocié la dépendance de la connexion à la source de données de la classe de référentiel, permettant ainsi à toute source de données de fonctionner avec le référentiel, et pas uniquement celle spécifiée par le référentiel.
Vous avez inversé le contrôle en confiant la responsabilité de la création de la connexion de la classe de référentiel à l'appelant.
Martin Fowler suggère d'utiliser le terme "Injection de dépendance" pour décrire ce type d'inversion de contrôle, étant donné que le concept d'inversion de contrôle peut être appliqué plus largement que la simple injection de dépendances dans une méthode constructeur.
la source
Je pense que personne ne peut mieux l'expliquer que Martin Fowler, plus loin dans l'article que vous avez lié .
Comme il l'explique dans les paragraphes ci-dessus, ce n'est pas tout à fait la même raison que le terme "Inversion of Control".
C’est pourquoi il invente le terme «injection de dépendance» pour couvrir cette implémentation spécifique de l’inversion du contrôle.
Pour clarifier un peu: Inversion de contrôle signifie tout ce qui inverse la structure de contrôle d'un programme à partir de la conception procédurale classique.
Autrefois, un exemple clé consistait à laisser un cadre gérer la communication entre une interface utilisateur et votre code, plutôt que de laisser votre code générer directement l'interface utilisateur.
À une époque plus récente (lorsque de tels cadres dominaient à peu près, la question n'était donc plus d'actualité), un exemple consistait à inverser le contrôle sur l'instanciation d'objets.
Fowler et d’autres ont décidé que le terme Inversion of Control couvrait trop de techniques et que nous avions besoin d’un nouveau terme pour désigner un exemple spécifique d’instanciation d’objets (Dependency Injection), mais, au moment où cet accord avait été conclu, le terme "avait décollé.
Cela brouille beaucoup l'eau, car un conteneur IoC est un type spécifique d'injection de dépendance, mais l'injection de dépendance est un type spécifique d'inversion de contrôle. C'est pourquoi vous obtenez des réponses aussi confuses, peu importe où vous regardez.
la source
Voici les programmes de flux de contrôle "normaux" habituellement suivis:
L'inversion de contrôle "inverse" ce flux de contrôle, ce qui signifie qu'il le retourne sur sa tête:
Cette dernière ligne est la plus importante. Plutôt que d'appeler quelqu'un d'autre quand vous en avez envie, quelqu'un d'autre vous appelle quand ils en ont envie.
Un exemple courant est celui des frameworks Web tels que Rails. Vous définissez les contrôleurs, mais vous ne décidez pas quand ils seront appelés. Rails les appelle quand il le décide.
la source
Il s'agit de savoir qui contrôle l'instanciation des dépendances.
Traditionnellement, quand une classe / méthode doit utiliser une autre classe (dépendance), elle est instanciée directement par la classe / méthode. Il contrôle ses dépendances.
Avec Inversion of Control (IoC), l' appelant est passé dans la dépendance, d'où il instancie la dépendance. L'appelant contrôle les dépendances.
Le contrôle de l'endroit où une dépendance est instanciée a été inversé - au lieu d'être dans le "bas", où se trouve le code qui en a besoin, il est instancié dans le "haut", où le code qui en a besoin est appelé.
la source
Généralement, les appels de code de niveau supérieur (c.-à-d. Les commandes) code de niveau inférieur Main () appelle function (), function () appelle libraryFunction ().
Cela peut être inversé, ainsi la fonction de bibliothèque de bas niveau au bas appelle des fonctions de niveau supérieur.
Pourquoi ferais-tu ça? Middleware. Parfois, vous voulez contrôler le niveau le plus élevé et le niveau le plus bas, mais vous ne voulez pas trop travailler au milieu. Prenez l'implémentation de quicksort dans C stdlib . Vous appelez quicksort au plus haut niveau. Vous remettez à qsort () un pointeur de fonction sur votre propre fonction qui implémente un comparateur sur ce que vous souhaitez. Lorsque qsort () est appelé, il appelle cette fonction de comparateur. qsort () contrôle / appelle / pilote votre fonction de haut niveau.
la source
Voici un aperçu simple:
Dans l'ancien temps, le contrôle appartenait d'abord à l'application, puis à l'utilisateur. Si l'application avait besoin de quelque chose de la part de l'utilisateur, elle s'arrêterait et demanderait, puis passerait à la tâche suivante. L'interaction de l'utilisateur fournissait principalement des données plutôt que de contrôler ce que l'application faisait ensuite. Cela nous est un peu étranger de nos jours car nous ne voyons pas ce type de comportement très souvent.
Si nous inversons la situation et donnons à l'utilisateur le contrôle principal, nous avons inversé le contrôle. Cela signifie qu'au lieu d'attendre que l'application lui donne quelque chose à faire, l'application attend que l'utilisateur lui donne quelque chose à faire. Les interfaces graphiques en sont un excellent exemple. Pratiquement tout ce qui a une boucle d’événement a un contrôle inversé.
Notez que mon exemple est au niveau supérieur et que ce concept d'inversion de contrôle peut être résumé à différentes couches de contrôle au sein de l'application (c'est-à-dire l'injection de dépendance). C'est peut-être pourquoi il est si difficile d'obtenir une réponse directe.
la source
Essayons de le comprendre à travers les deux exemples.
Exemple 1
Auparavant, les applications utilisées pour générer des invites de commande acceptaient les entrées utilisateur les unes après les autres. Aujourd'hui, les infrastructures d'interface utilisateur instancient divers éléments d'interface utilisateur, parcourent divers événements de ces éléments (comme le survol de la souris, le clic, etc.) et les programmes utilisateur / principaux fournissent des points d'ancrage (par exemple, des écouteurs d'événements d'interface utilisateur en Java) pour écouter ces événements. Ainsi, le "contrôle" principal du flux d'éléments d'interface utilisateur est déplacé du programme utilisateur vers le cadre de l'interface utilisateur. Dans les premiers jours, c'était dans le programme utilisateur.
Exemple 2
Considérez la classe
CustomerProcessor
ci - dessous:Si je veux
processCustomer()
être indépendant de toute implémentation degetAllCusts()
, pas seulement celle fournie parSqlCustRepo
, je devrai me débarrasser de la ligne:SqlCustRepo custRepo = new SqlCustRepo()
et la remplacer par quelque chose de plus générique, capable d'accepter différents types d'implémentations, de telle sorte queprocessCustomers()
cela fonctionnera simplement pour toute mise en œuvre fournie. Le code ci-dessus (instanciation de la classe requiseSqlCustRepo
par la logique du programme principal) est une méthode traditionnelle et il n’atteint pas cet objectif de découplageprocessCustomers()
de la mise en œuvre degetAllCusts()
. En inversion de contrôle, le conteneur instancie la classe d'implémentation requise (spécifiée par, par exemple, configuration xml), l'injecte dans la logique de programme principale qui est liée selon les crochets spécifiés (par exemple, par@Autowired
annotation ou pargetBean()
méthode dans le cadre Spring).Permet de voir comment cela peut être fait. Considérez ci-dessous le code.
Config.xml
CustRepo.java
JsonCustRepo.java
App.java
Nous pouvons aussi avoir
et
et nous n'aurons pas besoin de changer App.java.
Au-dessus du conteneur (qui est le framework Spring), il incombe d'analyser le fichier xml, d'instancier le bean d'un type spécifique et de l'injecter dans le programme utilisateur. Le programme utilisateur n'a aucun contrôle sur la classe instanciée.
PS: IoC est un concept générique et est atteint à bien des égards. Les exemples ci-dessus y parviennent par injection de dépendance.
Référence: article de Martin Fowler .
la source