Qu'est-ce que l'inversion de contrôle?

1827

L'inversion de contrôle (IoC) peut être assez déroutante lorsqu'elle est rencontrée pour la première fois.

  1. Qu'Est-ce que c'est?
  2. Quel problème résout-il?
  3. Quand est-il approprié d'utiliser et quand non?
Mike Minutillo
la source
292
Le problème avec la plupart de ces réponses est la terminologie utilisée. Qu'est-ce qu'un conteneur? Inversion? Dépendance? Expliquez-le en termes simples sans les grands mots.
kirk.burleson
13
Voir aussi sur Programmers.SE: Pourquoi l'inversion du contrôle est-elle ainsi nommée?
Izkata
8
C'est l'injection de dépendance (DI) - voir la description de Martin Fowlers ici: martinfowler.com/articles/injection.html#InversionOfControl
Ricardo Sanchez
C'est un adjectif, pas un nom, ce n'est pas une chose, c'est la description d'une modification apportée au code, où le contrôle du flux est dans le délégué, pas dans le conteneur.
Martin Spamer

Réponses:

1524

Les modèles d'inversion de contrôle (IoC) et d'injection de dépendance (DI) visent à supprimer les dépendances de votre code.

Par exemple, supposons que votre application possède un composant éditeur de texte et que vous souhaitiez effectuer une vérification orthographique. Votre code standard ressemblerait à 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 TextEditoret 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 instancions SpellChecker( this.checker = new SpellChecker();), ce qui signifie que la TextEditorclasse dépend directement de la SpellCheckerclasse.

Dans le deuxième exemple de code, nous créons une abstraction en ayant la SpellCheckerclasse de dépendance dans TextEditorla signature du constructeur de (pas en initialisant la dépendance dans la classe). Cela nous permet d'appeler la dépendance puis de la passer à la classe TextEditor comme ceci:

SpellChecker sc = new SpellChecker; // dependency
TextEditor textEditor = new TextEditor(sc);

Maintenant, le client qui crée la TextEditorclasse a le contrôle sur l' SpellCheckerimplémentation à utiliser car nous injectons la dépendance dans la TextEditorsignature.

urini
la source
50
Bon exemple clair. Cependant, supposons qu'au lieu d'exiger que l'interface ISpellChecker soit transmise au constructeur de l'objet, nous l'avons exposée en tant que propriété réglable (ou méthode SetSpellChecker). Est-ce que cela constituerait toujours l'IoC?
devios1
25
chainguy1337 - oui, ce serait le cas. 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). L'IoC est un modèle assez générique, mais l'injection de dépendances atteint l'IoC
Jack Ukleja
257
Malgré les nombreux votes positifs, cette réponse est incorrecte. Veuillez consulter martinfowler.com/articles/injection.html#InversionOfControl . En particulier, notez la partie disant "Inversion de contrôle est un terme trop générique, et donc les gens le trouvent déroutant. En conséquence, avec beaucoup de discussions avec divers défenseurs de l'IoC, nous avons choisi le nom Dependency Injection".
Rogério
45
Je suis d'accord avec @Rogeria. cela n'explique pas pourquoi on l'appelle l'IoC et je suis surpris par le nombre de votes positifs ;-)
Aravind Yarram
31
Je me range du côté de @Rogerio et @Pangea. Cela peut être un bon exemple pour l' injection de constructeur mais pas une bonne réponse à la question d'origine. L'IoC, tel que défini par Fowler , peut être réalisé sans utiliser d'injection d'aucune sorte, par exemple en utilisant un localisateur de service ou même un simple héritage.
mtsz
642

Inversion de contrôle est ce que vous obtenez lorsque votre programme rappelle, par exemple comme un programme GUI.

Par exemple, dans un menu old school, vous pourriez avoir:

print "enter your name"
read name
print "enter your address"
read address
etc...
store in database

contrôlant ainsi le flux d'interaction de l'utilisateur.

Dans un programme GUI ou un peu, au lieu de cela, nous disons:

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

Alors maintenant, le contrôle est 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 entrées et le moment où les données sont enregistrées dans la base de données.

Fondamentalement, tout ce qui a une boucle d'événements, des rappels ou des déclencheurs d'exécution tombe dans cette catégorie.

Mark Harrison
la source
161
ne marque 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)
Jack Ukleja
38
D'accord avec le commentaire de Schneider. 5 votes négatifs? L'esprit s'embrouille, car c'est la seule réponse qui est vraiment correcte. Notez l'ouverture: « comme un programme gui». L'injection de dépendance n'est que la réalisation la plus courante de l'IoC.
Jeff Sternal
40
En effet, c'est l'une des rares réponses correctes ! Les gars, l'IoC n'est pas fondamentalement une question de dépendances. Pas du tout.
Rogério
13
+1 - Ceci est une bonne description (avec un exemple) de la déclaration suivante de Martin Fowler - "Les premières interfaces utilisateur étaient contrôlées par le programme d'application. Vous auriez une séquence de commandes comme" Entrez le nom "," entrez l'adresse "; votre programme piloterait les invites et prendrait une réponse à chacune. Avec des interfaces graphiques (ou même basées sur l'écran), le cadre de l'interface utilisateur contiendrait cette boucle principale et votre programme fournissait à la place des gestionnaires d'événements pour les différents champs à l'écran. Le contrôle principal de le programme a été inversé, éloigné de vous vers le cadre. "
Ashish Gupta
14
Je comprends maintenant pourquoi il est parfois appelé facétieusement le "Principe d'Hollywood: ne nous appelez pas, nous vous appellerons"
Alexander Suraphel
419

Qu'est-ce que l'inversion de contrôle?

Si vous suivez ces deux étapes simples, vous avez effectué une inversion de contrôle:

  1. Séparer ce -À-faire partie de quand -À-faire partie.
  2. Assurez-vous que lorsqu'une partie connaît le moins possible de quelle partie; et vice versa.

Il existe plusieurs techniques possibles pour chacune de ces étapes en fonction de la technologie / du langage que vous utilisez pour votre implémentation.

-

La partie inversion de l'inversion de contrôle (IoC) est une chose déroutante; parce que l' inversion est le terme relatif. La meilleure façon de comprendre l'IoC est d'oublier ce mot!

-

Exemples

  • Gestion des événements. Gestionnaires d'événements (partie à faire) - Déclencher des événements (partie à faire)
  • Interfaces. Client de composant (partie à faire) - Implémentation de l'interface de composant (partie à faire)
  • Fixation xUnit. Setup et TearDown (partie à faire) - xUnit frameworks appelle à Setup au début et à TearDown à la fin (quand-à-faire)
  • Modèle de conception de méthode modèle. méthode méthode partie à faire - implémentation d'une sous-classe primitive partie à faire
  • Méthodes de conteneur DLL dans COM. DllMain, DllCanUnload, etc (partie quoi faire) - COM / OS (partie quand faire)
rpattabi
la source
Comment vous dites Interfaces. Le client de composant (partie à faire) comme "quand" n'a pas de sens lorsque nous utilisons des interfaces (Ex: injection de dépendance), nous le résumons simplement et donnons au client la flexibilité d'ajouter une implémentation, mais il n'y a pas de "quand" impliqués là-bas. Je suis d'accord avec "quand" en cas de déclenchement d'événements de gestion d'événements.
OldSchool
Par «client composant», j'entendais l'utilisateur / client de l'interface. Le client sait «quand» déclencher la partie «que faire» si l'intention est d'étendre la fonctionnalité ou non.
rpattabi
Jetez un œil à ce merveilleux article de Martin Fowler. Il montre comment les interfaces font la partie fondamentale de l'inversion de contrôle: martinfowler.com/articles/injection.html#InversionOfControl
rpattabi
deux premières phrases sont brillantes. impressionnant !! séparation parfaite par quand et quoi faire !! Je ne sais pas pourquoi les autres réponses obtiennent autant de votes positifs. ils parlent juste des codes sans aucune compréhension.
Amir Ziarati
2
J'aime l'explication what-to-doetwhen-to-do
KimchiMan
164

L'inversion des contrôles consiste à séparer les préoccupations.

Sans IoC : vous avez un ordinateur portable et vous cassez accidentellement l'écran. Et sacrément, vous trouverez le même modèle d'écran d'ordinateur portable nulle part sur le marché. Vous êtes donc coincé.

Avec IoC : vous avez un ordinateur de bureau et vous cassez accidentellement l'écran. Vous constatez que vous pouvez simplement saisir presque n'importe quel moniteur de bureau sur le marché, et cela fonctionne bien avec votre bureau.

Votre bureau implémente avec succès l'IoC dans ce cas. Il accepte une variété de moniteurs, contrairement à l'ordinateur portable, il a besoin d'un écran spécifique pour être réparé.

Luo Jiong Hui
la source
1
@Luo Jiong Hui Belle explication.
Sachin
3
La plupart des modèles de conception, sinon tous, ont leurs homologues dans notre vie quotidienne que nous voyons et comprenons si bien. La façon la plus efficace de comprendre un modèle de conception est de connaître leurs homologues de la vie quotidienne. Et je crois qu'il y en a beaucoup.
Luo Jiong Hui
6
Réponse incorrecte. Vous expliquez l' injection de dépendance et non l'IoC. Voir le commentaire de Rogério sur cette réponse ci
MickyD
2
Je suis d'accord. C'est DI, pas IoC. Obtient toujours un vote positif, car il s'agit d'une approche simple, tout en aidant à élargir la compréhension du sujet.
Mär
Il explique l'injection de dépendance. Pas Ioc. Mais explication agréable et claire.
Chamin Wickramarathna
120

L'inversion de contrôle (ou IoC), c'est obtenir la liberté (vous vous mariez, vous avez perdu la liberté et vous êtes contrôlé. Vous avez divorcé, vous venez de mettre en œuvre l'inversion de contrôle. C'est ce que nous avons appelé "découplé". Bon système informatique décourage certaines relations très étroites.) plus de flexibilité (la cuisine de votre bureau ne sert que de l'eau du robinet propre, c'est votre seul choix lorsque vous voulez boire. Votre patron a mis en place l'inversion de contrôle en installant une nouvelle machine à café. flexibilité de choisir de l'eau du robinet ou du café.) et moins de dépendance (Votre partenaire a un travail, vous n'avez pas de travail, vous dépendez financièrement de votre partenaire, donc vous êtes contrôlé. Vous trouvez un travail, vous avez mis en œuvre l'inversion de contrôle. Un bon système informatique encourage l'indépendance.)

Lorsque vous utilisez un ordinateur de bureau, vous avez asservi (ou dites contrôlé). Vous devez vous asseoir devant un écran et le regarder. Utiliser le clavier pour taper et utiliser la souris pour naviguer. Et un logiciel mal écrit peut vous asservir encore plus. Si vous remplacez votre ordinateur de bureau par un ordinateur portable, vous avez quelque peu inversé le contrôle. Vous pouvez facilement le prendre et vous déplacer. Alors maintenant, vous pouvez contrôler où vous êtes avec votre ordinateur, au lieu de le contrôler.

En implémentant Inversion of Control, un consommateur de logiciel / objet obtient plus de contrôles / d'options sur le logiciel / les objets, au lieu d'être contrôlé ou d'avoir moins d'options.

Avec les idées ci-dessus à l'esprit. Nous manquons encore un élément clé de l'IoC. Dans le scénario IoC, le consommateur de logiciel / objet est un cadre sophistiqué. Cela signifie que le code que vous avez créé n'est pas appelé par vous-même. Expliquons maintenant pourquoi cette méthode fonctionne mieux pour une application Web.

Supposons que votre code soit un groupe de travailleurs. Ils ont besoin de construire une voiture. Ces travailleurs ont besoin d'un endroit et d'outils (un cadre logiciel) pour construire la voiture. UNE framework logiciel traditionnel sera comme un garage avec de nombreux outils. Les travailleurs doivent donc établir eux-mêmes un plan et utiliser les outils pour construire la voiture. Construire une voiture n'est pas une entreprise facile, il sera très difficile pour les travailleurs de planifier et de coopérer correctement. UNE modernele cadre logiciel sera comme une usine automobile moderne avec toutes les installations et les gestionnaires en place. Les travailleurs n'ont pas à faire de plan, les gestionnaires (qui font partie du cadre, ils sont les personnes les plus intelligentes et ont élaboré le plan le plus sophistiqué) aideront à coordonner afin que les travailleurs sachent quand faire leur travail (le cadre appelle votre code). Les travailleurs doivent simplement être suffisamment flexibles pour utiliser tous les outils que les gestionnaires leur donnent (en utilisant l'injection de dépendance).

Bien que les travailleurs donnent le contrôle de la gestion du projet au plus haut niveau aux gestionnaires (le cadre). Mais il est bon que certains professionnels aident. C'est le concept de l'IoC qui vient vraiment.

Les applications Web modernes avec une architecture MVC dépendent du cadre pour effectuer le routage d'URL et mettre en place des contrôleurs pour le cadre à appeler.

L'injection de dépendance et l'inversion du contrôle sont liées. L'injection de dépendance est au niveau micro et l'inversion de contrôle est au niveau macro . Vous devez manger chaque bouchée (implémenter DI) pour terminer un repas (implémenter IoC).

Luo Jiong Hui
la source
21
J'ai voté pour le DI comparé au mariage et l'IoC au divorce.
Marek Bar
"Bien que les travailleurs donnent le contrôle de la gestion du projet au plus haut niveau aux gestionnaires (le cadre). Mais il est bon d'avoir des professionnels pour aider. C'est le concept de l'IoC qui vient vraiment." - Premièrement, le contrôle est avec le gestionnaire. Pouvez-vous expliquer comment ce contrôle est inversé? Avec l'aide de professionnels (quel type de professionnel)? Comment ?
Istiaque Ahmed
@Istiaque Ahmed, comparé à un garage où les travailleurs ont le contrôle total de tout, les directeurs d'une usine automobile moderne contrôlent la production. Alors maintenant, les travailleurs sont contrôlés au lieu de contrôler. Sachez que les gestionnaires dans ce contexte font partie d'une usine automobile moderne, pas des travailleurs. Les professionnels sont les gestionnaires qui sont professionnels dans la planification et la fabrication de voitures.
Luo Jiong Hui
2
Message aux personnes mariées: ne divorcez pas maintenant, vos classes pour enfants peuvent également implémenter l'IoC.
Julian
Oui, c'est juste ma vision du mariage aussi IoC
balron
94

Avant d'utiliser Inversion of Control, vous devez être bien conscient du fait qu'il a ses avantages et ses inconvénients et vous devez savoir pourquoi vous l'utilisez si vous le faites.

Avantages:

  • Votre code est découplé afin que vous puissiez facilement échanger des implémentations d'une interface avec des implémentations alternatives
  • C'est un puissant facteur de motivation pour le codage par rapport aux interfaces plutôt qu'aux implémentations
  • Il est très facile d'écrire des tests unitaires pour votre code car il ne dépend de rien d'autre que des objets qu'il accepte dans son constructeur / setters et vous pouvez facilement les initialiser avec les bons objets de manière isolée.

Les inconvénients:

  • L'IoC non seulement inverse le flux de contrôle dans votre programme, mais le trouble également considérablement. Cela signifie que vous ne pouvez plus simplement lire votre code et sauter d'un endroit à un autre car les connexions qui seraient normalement dans votre code ne le sont plus. Au lieu de cela, c'est dans les fichiers de configuration XML ou les annotations et dans le code de votre conteneur IoC qui interprète ces métadonnées.
  • Il en résulte une nouvelle classe de bogues où vous obtenez une mauvaise configuration XML ou des annotations et vous pouvez passer beaucoup de temps à découvrir pourquoi votre conteneur IoC injecte une référence nulle dans l'un de vos objets sous certaines conditions.

Personnellement, je vois les points forts de l'IoC et je les aime vraiment, mais j'ai tendance à éviter l'IoC autant que possible car cela transforme votre logiciel en une collection de classes qui ne constituent plus un "vrai" programme mais juste quelque chose qui doit être mis en place par Configuration XML ou métadonnées d'annotation et s'effondreraient (et s'effondreraient) sans elle.

ahe
la source
3
Le premier con est incorrect. Idéalement, il ne devrait y avoir qu'une seule utilisation du conteneur IOC dans votre code, et c'est votre principale méthode. Tout le reste devrait descendre en cascade à partir de là
mwjackson
23
Je pense que ce qu'il veut dire, vous ne pouvez pas simplement lire: myService.DoSomething () et aller à la définition de DoSomething, car avec IoC, myService est juste une interface, et l'implémentation réelle vous est inconnue, à moins que vous ne regardiez il dans les fichiers de configuration xml ou la méthode principale où votre ioc obtient la configuration.
chrismay
7
C'est là que Resharper aide - "cliquez sur aller à l'implémentation" contre l'interface. Éviter l'IoC (ou plus spécifiquement DI de votre exemple) signifie également que vous ne testez pas correctement
IThasTheAnswer
10
Re: 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 une configuration XML ou des métadonnées d'annotation et qui s'effondrerait (et s'effondrerait) sans cela - je pense que cela est très trompeur. La même chose pourrait être dite de tout programme qui est écrit au-dessus d'un cadre. La différence avec un bon conteneur IoC est que vous devriez être en mesure, si votre programme est bien conçu et écrit, de le retirer et d'en insérer un autre avec un minimum de changements dans votre code, ou de jeter IoC complètement et de construire vos objets à la main .
The Awnry Bear
7
C'est bon de voir une réponse du monde réel comme celle-ci! Je pense qu'il y a beaucoup de programmeurs expérimentés, à l'aise avec la conception orientée objet et les pratiques TDD, qui utilisent déjà des interfaces, des modèles d'usine, des modèles pilotés par les événements et des moqueries là où cela a du sens, avant que ce mot à la mode "IoC" ne soit inventé. Malheureusement, trop de développeurs / "architectes" réclament de mauvaises pratiques si vous n'utilisez pas leurs frameworks préférés. Je préfère une meilleure conception, une utilisation des concepts et des outils de langage intégrés, pour atteindre le même objectif avec une fraction de la complexité, c'est-à-dire sans "opacifier" l'implémentation comme vous le dites :-)
Tony Wall
68
  1. Article Wikipédia . Pour moi, l'inversion du contrôle transforme votre code écrit séquentiellement et le transforme en une structure de délégation. Au lieu que votre programme contrôle tout explicitement, votre programme met en place une classe ou une bibliothèque avec certaines fonctions à appeler lorsque certaines choses se produisent.

  2. Il résout la duplication de code. Par exemple, autrefois, vous écriviez manuellement votre propre boucle d'événements, interrogeant les bibliothèques système pour de nouveaux événements. De nos jours, la plupart des API modernes vous permettent simplement d'indiquer aux bibliothèques système les événements qui vous intéressent, et cela vous permettra de savoir quand ils se produisent.

  3. L'inversion de contrôle est un moyen pratique de réduire la duplication de code, et si vous vous retrouvez à copier une méthode entière et à ne modifier qu'une petite partie du code, vous pouvez envisager de le résoudre avec l'inversion de contrôle. L'inversion du contrôle est facilitée dans de nombreux langages grâce au concept de délégués, d'interfaces ou même de pointeurs de fonctions brutes.

    Il n'est pas approprié de l'utiliser dans tous les cas, car le déroulement d'un programme peut être plus difficile à suivre lorsqu'il est écrit de cette façon. C'est un moyen 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, sauf si elle résout vraiment un problème de duplication de code.

NilObject
la source
37
Je trouve cet article Wikipedia très déroutant et a besoin d'être réparé. Consultez la page de discussion pour rire.
devios1
L'écriture de votre propre boucle d'événement pourrait toujours ê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. Ce n'est en fait pas une mauvaise chose, cela augmente la lisibilité au prix d'un peu plus de codage (pas que ce soit toujours approprié non plus).
lijat
45

Mais je pense que vous devez être très prudent avec cela. Si vous abusez de ce modèle, vous ferez une conception très compliquée et du code encore plus compliqué.

Comme dans cet exemple avec TextEditor: si vous n'avez qu'un seul correcteur orthographique, il n'est peut-être pas vraiment nécessaire d'utiliser IoC? Sauf si vous avez besoin d'écrire des tests unitaires ou quelque chose ...

Quoi qu'il en soit: soyez raisonnable. Les modèles de conception sont de bonnes pratiques, mais pas la Bible à prêcher. Ne le collez pas partout.

Michal Sznajder
la source
3
Comment savez-vous que vous n'aurez qu'un seul correcteur orthographique?
Trace le
@Trace Vous pourriez savoir par exemple comment le programme que vous allez écrire va être utilisé. Certaines techniques telles que l'injection de dépendance sont si bon marché qu'il y a rarement une raison de ne pas les utiliser dans un cas comme celui-ci.
lijat
44

Pour moi, l'IoC / DI repousse les dépendances vers les objets appelants. Super simple.

La réponse non technique est de pouvoir remplacer un moteur dans une voiture juste avant de l'allumer. Si tout se branche bien (l'interface), vous êtes bon.

ferventcoder
la source
44

Supposons que vous soyez un objet. Et vous allez au restaurant:

Sans IoC : vous demandez "pomme", et on vous sert toujours des pommes quand vous en demandez plus.

Avec IoC : vous pouvez demander des "fruits". Vous pouvez obtenir des fruits différents à chaque fois que vous êtes servi. par exemple, pomme, orange ou melon d'eau.

Donc, évidemment, l'IoC est préférable lorsque vous aimez les variétés.

Luo Jiong Hui
la source
26
  1. L'inversion de contrôle est un modèle utilisé pour découpler les composants et les couches dans le système. Le modèle est implémenté en injectant des dépendances dans un composant lors de sa construction. Ces dépendances sont généralement fournies en tant qu'interfaces pour un découplage ultérieur et pour prendre en charge la testabilité. Les conteneurs IoC / DI tels que Castle Windsor, Unity sont des outils (bibliothèques) qui peuvent être utilisés pour fournir l'IoC. Ces outils offrent des fonctionnalités étendues au-delà de la simple gestion des dépendances, y compris la durée de vie, AOP / Interception, la politique, etc.

  2. une. Évite à un composant d'être responsable de la gestion de ses dépendances.
    b. Fournit la possibilité d'échanger des implémentations de dépendance dans différents environnements.
    c. Permet à un composant d'être testé en se moquant des dépendances.
    ré. Fournit un mécanisme de partage des ressources dans une application.

  3. une. Critique lors du développement piloté par les tests. Sans IoC, il peut être difficile de tester, car les composants testés sont fortement couplés au reste du système.
    b. Critique lors du développement de systèmes modulaires. Un système modulaire est un système dont les composants peuvent être remplacés sans nécessiter de recompilation.
    c. Critique s'il existe de nombreuses préoccupations transversales qui doivent être traitées, en particulier dans une application d'entreprise.

Glenn Block
la source
2
En fait, l'IoC ne concerne pas principalement la gestion des dépendances. S'il vous plaît voir martinfowler.com/articles/injection.html#InversionOfControl En particulier, notez la partie disant "Inversion de contrôle est un terme trop générique, et donc les gens trouvent cela déroutant. En conséquence, avec beaucoup de discussions avec divers défenseurs IoC nous réglé sur le nom Dependency Injection ".
Rogério
26

Répondre à la première partie seulement. Qu'Est-ce que c'est?

L'inversion de contrôle (IoC) signifie créer des instances de dépendances en premier et dernier exemple d'une classe (en les injectant éventuellement via le constructeur), au lieu de créer d'abord une instance de la classe puis l'instance de classe en créant des instances de dépendances. Ainsi, l'inversion de contrôle inverse le flux de contrôle du programme. Au lieu que l' appelé contrôle le flux de contrôle (tout en créant des dépendances), l' appelant contrôle le flux de contrôle du programme .

user2330678
la source
Il ne s'agit pas de création de classe ou d'objet, consultez ce martinfowler.com/articles/injection.html#InversionOfControl
Raghvendra Singh
22

Je noterai ma simple compréhension de ces deux termes:

For quick understanding just read examples*

Injection de dépendance (DI): L'
injection de dépendance signifie généralement passer un objet dont la méthode dépend, en tant que paramètre à une méthode, plutôt que de demander à la méthode de créer l'objet dépendant .
En pratique, cela signifie que la méthode ne dépend pas directement d'une implémentation particulière; toute implémentation qui répond aux exigences peut être transmise en tant que paramètre.

Avec ces objets, dites leurs dépendances. Et le printemps le rend disponible.
Cela conduit à un développement d'applications faiblement couplé.

Quick Example:EMPLOYEE OBJECT WHEN CREATED,
              IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT
   (if address is defines as dependency by Employee object)

Conteneur d'inversion de contrôle (IoC):
C'est une caractéristique commune des frameworks, IOC gère les objets java
- de l'instanciation à la destruction via sa BeanFactory.
-Les composants Java qui sont instanciés par le conteneur IoC sont appelés beans, et le conteneur IoC gère la portée d'un bean, les événements de cycle de vie et toutes les fonctionnalités AOP pour lesquelles il a été configuré et codé.

QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it.

En implémentant Inversion of Control, un consommateur de logiciels / d'objets obtient plus de contrôles / d'options sur les logiciels / objets, au lieu d'être contrôlé ou d'avoir moins d'options.

L'inversion du contrôle en tant que guide de conception sert les objectifs suivants:

Il y a un découplage entre l'exécution d'une certaine tâche et la mise en œuvre.
Chaque module peut se concentrer sur ce pour quoi il est conçu.
Les modules ne font aucune hypothèse sur ce que font les autres systèmes mais s'appuient sur leurs contrats.
Le remplacement des modules n'a aucun effet secondaire sur les autres modules
Je vais garder les choses abstraites ici, vous pouvez visiter les liens suivants pour une compréhension détaillée du sujet.
Une bonne lecture avec exemple

Explication détaillée

VdeX
la source
17

Je suis d'accord avec NilObject , mais j'aimerais ajouter à cela:

si vous vous retrouvez à copier une méthode entière et à ne changer qu'une petite partie du code, vous pouvez envisager de l'aborder avec une inversion de contrôle

Si vous vous retrouvez à copier et coller du code, vous faites presque toujours quelque chose de mal. Codifié comme principe de conception une fois et une seule fois .

Peter Burns
la source
17

Par exemple, la tâche n ° 1 consiste à créer un objet. Sans concept IOC, la tâche n ° 1 est censée être effectuée par le programmeur, mais avec le concept IOC, la tâche n ° 1 serait effectuée par conteneur.

En bref, le contrôle est inversé du programmeur au conteneur. Ainsi, il est appelé inversion de contrôle.

J'ai trouvé un bon exemple ici .

gogs
la source
Un conteneur est un concept en IoC où le modèle d'objet, y compris les dépendances (relations entre l'objet "utilisateur" et l'objet "utilisé") et les instances d'objet, résident et sont gérés - par exemple, contenus. Le conteneur est généralement fourni par une infrastructure IoC, telle que Spring. Considérez-le comme un référentiel d'exécution pour les objets qui composent votre application.
The Awnry Bear
17

Disons que nous faisons une réunion dans un hôtel.

Beaucoup de gens, beaucoup de carafes d'eau, beaucoup de gobelets en plastique.

Quand quelqu'un veut boire, elle remplit la tasse, boit et jette la tasse par terre.

Après une heure ou quelque chose, nous avons un sol couvert de gobelets en plastique et d'eau.

Laissez inverser le contrôle.

La même réunion au même endroit, mais au lieu de gobelets en plastique, nous avons un serveur avec une tasse en verre (Singleton)

et elle offre tout le temps aux invités à boire.

Quand quelqu'un veut boire, elle sort du verre du serveur, boit et le rend au serveur.

Laissant de côté la question de l'hygiène, la dernière forme de contrôle du processus de consommation est beaucoup plus efficace et économique.

Et c'est exactement ce que fait le Spring (un autre conteneur IoC, par exemple: Guice). Au lieu de laisser l'application créer ce dont elle a besoin en utilisant un nouveau mot-clé (prendre un gobelet en plastique), le conteneur Spring IoC offre tout le temps à l'application la même instance (singleton) de l'objet nécessaire (verre d'eau).

Considérez-vous comme l'organisateur d'une telle réunion. Vous avez besoin d'un moyen de signaler à l'administration de l'hôtel que

les membres de la réunion auront besoin d'un verre d'eau mais pas d'un morceau de gâteau.

Exemple:-

public class MeetingMember {

    private GlassOfWater glassOfWater;

    ...

    public void setGlassOfWater(GlassOfWater glassOfWater){
        this.glassOfWater = glassOfWater;
    }
    //your glassOfWater object initialized and ready to use...
    //spring IoC  called setGlassOfWater method itself in order to
    //offer to meetingMember glassOfWater instance

}

Liens utiles:-

Jainendra
la source
les singletons ne sont-ils pas des objets de type statique?
Gokigooooks
16

Il semble que la chose la plus déroutante à propos de "IoC" l'acronyme et le nom qu'il représente est qu'il est trop glamour d'un nom - presque un nom de bruit.

Avons-nous vraiment besoin d'un nom pour décrire la différence entre la programmation procédurale et la programmation pilotée par les événements? D'accord, si nous en avons besoin, mais devons-nous choisir un tout nouveau nom «plus grand que nature» qui confond plus qu'il ne résout?

email.privacy
la source
1
IoC! = Piloté par les événements. Des similitudes (et dans certains cas se chevauchent), mais elles ne sont pas principalement le même paradigme.
The Awnry Bear
Bonne question. La programmation événementielle est certainement IoC. Nous écrivons des gestionnaires d'événements et ils sont appelés depuis la boucle d'événements. Mais l'IoC est un concept plus générique que la programmation basée sur les événements. Si vous remplacez une méthode dans la sous-classe, c'est aussi une sorte d'IoC. Vous écrivez un code qui serait invoqué lorsque la référence (instance) appropriée était utilisée.
vi.su.
15

L'inversion du contrôle, c'est quand vous allez à l'épicerie et que votre femme vous donne la liste des produits à acheter.

En termes de programmation, elle a transmis une fonction de rappel getProductList()à la fonction que vous exécutez - doShopping().

Il permet à l'utilisateur de la fonction d'en définir certaines parties, ce qui la rend plus flexible.

Sergiy Ostrovsky
la source
5
Ma femme fait généralement ses courses avec moi, mais je suis d'accord avec cette affirmation.
ha9u63ar
1
@ ha9u63ar Votre femme fait du shopping avec vous? Eh bien, cela s'appelle l'agrégation alors.
Julian
2
Si elle donne aussi l'argent, cela s'appelle DI.
San
1
Le mot Inversion - à l'envers - vient de quand votre femme getProductList()vous appelle, vous devez trouver la source de l'argent, signifie que le contrôle est à vos côtés. En cas d'inversion, elle contrôlera, c'est-à-dire l'argent qu'elle fournira également pour acheter.
San
13

J'ai trouvé un exemple très clair ici qui explique comment le «contrôle est inversé.

Code classique (sans injection de dépendance)

Voici comment fonctionne un code n'utilisant pas DI:

  • L'application a besoin de Foo (par exemple un contrôleur), donc:
  • L'application crée Foo
  • L'application appelle Foo
    • Foo a besoin de Bar (par exemple un service), donc:
    • Foo crée Bar
    • Foo appelle Bar
      • Bar a besoin de Bim (un service, un référentiel,…), donc:
      • Bar crée Bim
      • Le bar fait quelque chose

Utilisation de l'injection de dépendance

Voici comment fonctionne un code utilisant DI:

  • L'application a besoin de Foo, qui a besoin de Bar, qui a besoin de Bim, donc:
  • L'application crée Bim
  • L'application crée Bar et lui donne Bim
  • L'application crée Foo et lui donne Bar
  • L'application appelle Foo
    • Foo appelle Bar
      • Le bar fait quelque chose

Le contrôle des dépendances est inversé de celui qui est appelé à celui qui appelle.

Quels problèmes cela résout-il?

L'injection de dépendances facilite l'échange avec les différentes implémentations des classes injectées. Lors des tests unitaires, vous pouvez injecter une implémentation factice, ce qui facilite considérablement les tests.

Ex: Supposons que votre application stocke le fichier téléchargé par l'utilisateur dans Google Drive, avec DI votre code de contrôleur peut ressembler à ceci:

class SomeController
{
    private $storage;

    function __construct(StorageServiceInterface $storage)
    {
        $this->storage = $storage;
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

class GoogleDriveService implements StorageServiceInterface
{
    public function authenticate($user) {}
    public function putFile($file) {}
    public function getFile($file) {}
}

Lorsque vos besoins changent, par exemple, au lieu de GoogleDrive, vous êtes invité à utiliser Dropbox. Il vous suffit d'écrire une implémentation de dropbox pour StorageServiceInterface. Vous n'avez aucune modification à apporter au contrôleur tant que l'implémentation de Dropbox adhère à StorageServiceInterface.

Pendant les tests, vous pouvez créer la maquette pour StorageServiceInterface avec l'implémentation factice où toutes les méthodes renvoient null (ou toute valeur prédéfinie selon vos exigences de test).

Au lieu de cela, si vous aviez la classe contrôleur pour construire l'objet de stockage avec le newmot clé comme ceci:

class SomeController
{
    private $storage;

    function __construct()
    {
        $this->storage = new GoogleDriveService();
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

Lorsque vous souhaitez changer avec l'implémentation Dropbox, vous devez remplacer toutes les lignes où new objet GoogleDriveService est construit et utiliser DropboxService. En outre, lors du test de la classe SomeController, le constructeur attend toujours la classe GoogleDriveService et les méthodes réelles de cette classe sont déclenchées.

Quand est-ce approprié et quand non? À mon avis, vous utilisez DI lorsque vous pensez qu'il existe (ou qu'il peut y avoir) des implémentations alternatives d'une classe.

Raghavendra N
la source
Ce devrait être la réponse la plus correcte car c'est la seule qui explique comment le "contrôle" est inversé.
Yarimadam
meilleure explication à ce jour
Ali80
12

Une explication écrite très simple peut être trouvée ici

http://binstock.blogspot.in/2008/01/excellent-explanation-of-dependency.html

Ça dit -

"Toute application non triviale est composée de deux classes ou plus qui collaborent pour exécuter une logique métier. Traditionnellement, chaque objet est responsable d'obtenir ses propres références aux objets avec lesquels il collabore (ses dépendances). Lors de l'application de DI, le les objets reçoivent leurs dépendances au moment de la création par une entité externe qui coordonne chaque objet dans le système. En d'autres termes, les dépendances sont injectées dans les objets. "

agaase
la source
12

L'inversion de contrôle est un principe générique, tandis que l'injection de dépendances réalise ce principe comme un modèle de conception pour la construction de graphes d'objets (c'est-à-dire que la configuration contrôle la façon dont les objets se référencent les uns les autres, plutôt que l'objet lui-même contrôlant comment obtenir la référence à un autre objet).

En regardant l'inversion du contrôle comme modèle de conception, nous devons examiner ce que nous inversons. L'injection de dépendance inverse le contrôle de la construction d'un graphe d'objets. Si elle est dite en termes simples, l'inversion de contrôle implique un changement de flux de contrôle dans le programme. Par exemple. Dans l'application autonome traditionnelle, nous avons la méthode principale, à partir de laquelle le contrôle est passé à d'autres bibliothèques tierces (dans le cas où nous avons utilisé la fonction de bibliothèque tierce), mais par l'inversion du contrôle, le contrôle est transféré du code de bibliothèque tiers vers notre code , car nous prenons le service d'une bibliothèque tierce. Mais il y a d'autres aspects qui doivent être inversés dans un programme - par exemple l'invocation de méthodes et de threads pour exécuter le code.

Pour ceux qui souhaitent approfondir l'inversion du contrôle, un article a été publié décrivant une image plus complète de l'inversion du contrôle en tant que modèle de conception (OfficeFloor: utiliser les modèles de bureau pour améliorer la conception de logiciels http://doi.acm.org/10.1145/ 2739011.2739013 avec une copie gratuite disponible en téléchargement sur http://www.officefloor.net/about.html ).

Ce qui est identifié est la relation suivante:

Inversion de contrôle (pour les méthodes) = Dépendance (état) Injection + Continuation Injection + Thread Injection

Résumé de la relation ci-dessus pour l'inversion de contrôle disponible - http://dzone.com/articles/inversion-of-coupling-control

Daniel Sagenschneider
la source
C'est une réponse très claire. Merci pour l'explication.
KunYu Tsai du
11

L'IoC consiste à inverser la relation entre votre code et le code tiers (bibliothèque / framework):

  • Dans le développement s / w normal, vous écrivez la méthode main () et appelez les méthodes "bibliothèque". Vous avez le contrôle :)
  • Dans IoC, le "framework" contrôle main () et appelle vos méthodes. Le Framework est sous contrôle :(

DI (Dependency Injection) concerne la façon dont le contrôle circule dans l'application. L'application de bureau traditionnelle avait un flux de contrôle de votre application (méthode main ()) vers d'autres appels de méthode de bibliothèque, mais avec le flux de contrôle DI est inversé, le cadre prend soin de démarrer votre application, de l'initialiser et d'appeler vos méthodes chaque fois que nécessaire.

En fin de compte, vous gagnez toujours :)

Khanh
la source
10

J'aime cette explication: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

Il démarre simplement et montre également des exemples de code.

entrez la description de l'image ici

Le consommateur, X, a besoin de la classe consommée, Y, pour accomplir quelque chose. C'est tout bon et naturel, mais X a-t-il vraiment besoin de savoir qu'il utilise Y?

N'est-ce pas suffisant que X sache qu'il utilise quelque chose qui a le comportement, les méthodes, les propriétés, etc. de Y sans savoir qui implémente réellement le comportement?

En extrayant une définition abstraite du comportement utilisé par X dans Y, illustré comme I ci-dessous, et en laissant le consommateur X utiliser une instance de cela au lieu de Y, il peut continuer à faire ce qu'il fait sans avoir à connaître les spécificités de Y.

entrez la description de l'image ici

Dans l'illustration ci-dessus, Y implémente I et X utilise une instance de I. Bien qu'il soit tout à fait possible que X utilise toujours Y, ce qui est intéressant, c'est que X ne le sait pas. Il sait juste qu'il utilise quelque chose qui implémente I.

Lisez l'article pour plus d'informations et une description des avantages tels que:

  • X ne dépend plus de Y
  • Plus flexible, la mise en œuvre peut être décidée lors de l'exécution
  • Isolement de l'unité de code, tests plus faciles

...

DDan
la source
Le lien est très utile. Vraiment merci :)
M Fuat NUROĞLU
10

Je comprends que la réponse a déjà été donnée ici. Mais je pense toujours que certains principes de base de l'inversion de contrôle doivent être discutés ici en détail pour les futurs lecteurs.

L'inversion de contrôle (IoC) a été construite sur un principe très simple appelé Hollywood Principle . Et ça dit que,

Ne nous appelez pas, nous vous appellerons

Ce que cela signifie, c'est de ne pas aller à Hollywood pour réaliser votre rêve plutôt que si vous en êtes digne, alors Hollywood vous trouvera et réalisera votre rêve. À peu près inversé, hein?

Maintenant, quand nous discutons du principe de l'IoC, nous oublions Hollywood. Pour IoC, il doit y avoir trois éléments, un Hollywood, vous et une tâche comme réaliser votre rêve.

Dans notre monde de programmation, Hollywood représente un cadre générique (peut être écrit par vous ou quelqu'un d'autre), vous représentez le code utilisateur que vous avez écrit et la tâche représente la chose que vous voulez accomplir avec votre code. Maintenant, vous n'allez jamais déclencher votre tâche par vous-même, pas en IoC! Vous avez plutôt tout conçu de telle sorte que votre framework déclenche votre tâche pour vous. Ainsi, vous avez construit un cadre réutilisable qui peut faire de quelqu'un un héros ou un autre un méchant. Mais ce cadre est toujours en charge, il sait quand choisir quelqu'un et que quelqu'un ne sait que ce qu'il veut être.

Un exemple concret serait donné ici. Supposons que vous souhaitiez développer une application Web. Ainsi, vous créez un cadre qui gérera toutes les choses courantes qu'une application Web devrait gérer comme la gestion des requêtes http, la création de menu d'application, la diffusion de pages, la gestion des cookies, le déclenchement d'événements, etc.

Et ensuite, vous laissez des crochets dans votre cadre où vous pouvez mettre d'autres codes pour générer un menu personnalisé, des pages, des cookies ou enregistrer certains événements utilisateur, etc. au navigateur.

Donc, l'idée est assez simple. Plutôt que de créer une application utilisateur qui contrôlera tout, vous créez d'abord un cadre réutilisable qui contrôlera tout, puis écrivez vos codes personnalisés et les raccordez au cadre pour les exécuter à temps.

Laravel et EJB sont des exemples de tels cadres.

Référence:

https://martinfowler.com/bliki/InversionOfControl.html

https://en.wikipedia.org/wiki/Inversion_of_control

Abdullah Al Farooq
la source
1
La réponse la plus appropriée que j'ai trouvée ici.
blueray
8

Programmation parlant

IoC en termes simples: c'est l'utilisation d'Interface comme moyen de quelque chose de spécifique (un tel champ ou un paramètre) en tant que caractère générique qui peut être utilisé par certaines classes. Il permet la réutilisation du code.

Par exemple, disons que nous avons deux classes: chien et chat . Les deux partagent les mêmes qualités / états: âge, taille, poids. Ainsi, au lieu de créer une classe de service appelée DogService et CatService , je peux en créer une seule appelée AnimalService qui permet d'utiliser Dog et Cat uniquement s'ils utilisent l'interface IAnimal .

Cependant, de façon pragmatique, il en a en arrière.

a) La plupart des développeurs ne savent pas comment l'utiliser . Par exemple, je peux créer une classe appelée Customer et je peux créer automatiquement (à l'aide des outils de l'EDI) une interface appelée ICustomer . Il n'est donc pas rare de trouver un dossier rempli de classes et d'interfaces, que les interfaces soient réutilisées ou non. Ça s'appelle BLOATED. Certaines personnes pourraient soutenir que "peut-être à l'avenir, nous pourrions l'utiliser". : - |

b) Il a quelques limites. Par exemple, parlons du cas de Dog and Cat et je veux ajouter un nouveau service (fonctionnalité) uniquement pour les chiens. Disons que je veux calculer le nombre de jours dont j'ai besoin pour former un chien ( trainDays()), pour le chat c'est inutile, les chats ne peuvent pas être dressés (je plaisante).

b.1) Si j'ajoute trainDays()au Service AnimalService, cela fonctionne également avec les chats et ce n'est pas valable du tout.

b.2) Je peux ajouter une condition dans trainDays()laquelle il évalue quelle classe est utilisée. Mais cela brisera complètement l'IoC.

b.3) Je peux créer une nouvelle classe de service appelée DogService juste pour la nouvelle fonctionnalité. Mais, cela augmentera la maintenabilité du code car nous aurons deux classes de service (avec des fonctionnalités similaires) pour Dog et c'est mauvais.

magallanes
la source
À propos des classes / interfaces gonflées: vous n'avez pas toujours à réutiliser chaque interface. Parfois, il est logique de diviser une grande interface en plusieurs plus petites pour voir ses limites fonctionnelles. Les interfaces plus petites sont également plus faciles à réutiliser dans d'autres implémentations. Il vous encourage également à coder vers une interface là où cela a du sens. Envisagez la "séparation d'interface". Ce n'est pas parce que vous utilisez une interface que vous êtes découplé. Une seule interface grasse est inutile. - Juste mes 2 cents :)
MK
7

J'ai lu beaucoup de réponses pour cela, mais si quelqu'un est toujours confus et a besoin d'un "terme profane" ultra pour expliquer l'IoC, voici ma position:

Imaginez un parent et un enfant qui se parlent.

Sans IoC:

*Parent : Vous ne pouvez parler que lorsque je vous pose des questions et vous ne pouvez agir que lorsque je vous donne la permission.

Parent : Cela signifie que vous ne pouvez pas me demander si vous pouvez manger, jouer, aller aux toilettes ou même dormir si je ne vous le demande pas.

Parent : Voulez-vous manger?

Enfant : Non.

Parent : D'accord, je reviens. Attends-moi.

Enfant : (Veut jouer mais puisqu'il n'y a pas de question du parent, l'enfant ne peut rien faire).

Après 1 heure...

Parent : je suis de retour. Tu veux jouer?

Enfant : oui.

Parent : Permission accordée.

Enfant : (enfin capable de jouer).

Ce scénario simple explique que le contrôle est centré sur le parent. La liberté de l'enfant est limitée et dépend fortement de la question des parents. L'enfant peut SEULEMENT parler lorsqu'il lui est demandé de parler, et peut SEULEMENT agir sur autorisation.

Avec IoC:

L'enfant a désormais la possibilité de poser des questions et le parent peut répondre avec des réponses et des autorisations. Signifie simplement que le contrôle est inversé! L'enfant est maintenant libre de poser des questions à tout moment et bien qu'il y ait toujours une dépendance avec le parent concernant les autorisations, il n'est pas dépendant des moyens de parler / de poser des questions.

D'une manière technologique d'expliquer, cela est très similaire à l'interaction console / shell / cmd vs GUI. (Qui est la réponse de Mark Harrison au-dessus de la réponse n ° 2). Dans la console, vous dépendez de ce qui vous est demandé / affiché et vous ne pouvez pas accéder à d'autres menus et fonctionnalités sans répondre d'abord à la question; suivant un flux séquentiel strict. (par programmation, c'est comme une boucle méthode / fonction). Cependant, avec l'interface graphique, les menus et les fonctionnalités sont présentés et l'utilisateur peut sélectionner tout ce dont il a besoin, ayant ainsi plus de contrôle et étant moins restreint. (par programmation, les menus sont rappelés lorsqu'ils sont sélectionnés et une action a lieu).

Reuben JaMes Aveño Gruta
la source
6

L'inversion du contrôle consiste à transférer le contrôle de la bibliothèque au client. Cela a plus de sens lorsque nous parlons d'un client qui injecte (passe) une valeur de fonction (expression lambda) dans une fonction d'ordre supérieur (fonction de bibliothèque) qui contrôle (modifie) le comportement de la fonction de bibliothèque. Un client ou un framework qui injecte des dépendances de bibliothèque (qui ont un comportement) dans les bibliothèques peut également être considéré comme IoC

Sergiu Starciuc
la source
5

Étant donné qu'il existe déjà de nombreuses réponses à la question, mais qu'aucune d'entre elles ne montre la ventilation du terme de contrôle d'inversion, je vois une occasion de donner une réponse plus concise et utile.

L'inversion de contrôle est un modèle qui met en œuvre le principe d'inversion de dépendance (DIP). DIP indique ce qui suit: 1. Les modules de haut niveau ne doivent pas dépendre de modules de bas niveau. Les deux devraient dépendre d'abstractions (par exemple des interfaces). 2. Les abstractions ne devraient pas dépendre des détails. Les détails (implémentations concrètes) doivent dépendre des abstractions.

Il existe trois types d'inversion de contrôle:

Les fournisseurs d' inversion d'interface ne doivent pas définir d'interface. Au lieu de cela, le consommateur doit définir l'interface et les fournisseurs doivent la mettre en œuvre. L'interface d'inversion permet d'éliminer la nécessité de modifier le consommateur à chaque fois qu'un nouveau fournisseur s'ajoute.

Inversion de flux Change le contrôle du flux. Par exemple, vous avez une application console dans laquelle vous avez demandé d'entrer de nombreux paramètres et après chaque paramètre entré, vous êtes obligé d'appuyer sur Entrée. Vous pouvez appliquer Flow Inversion ici et implémenter une application de bureau où l'utilisateur peut choisir la séquence de saisie des paramètres, l'utilisateur peut modifier les paramètres et à la dernière étape, l'utilisateur doit appuyer sur Entrée une seule fois.

Inversion de création Elle peut être implémentée par les modèles suivants: modèle d'usine, localisateur de service et injection de dépendances. L'inversion de création permet d'éliminer les dépendances entre les types en déplaçant le processus de création d'objets de dépendance en dehors du type qui utilise ces objets de dépendance. Pourquoi les dépendances sont mauvaises? Voici quelques exemples: la création directe d'un nouvel objet dans votre code rend les tests plus difficiles; il est impossible de modifier les références dans les assemblys sans recompilation (violation du principe OCP); vous ne pouvez pas facilement remplacer une interface utilisateur de bureau par une interface utilisateur Web.

Vadim S.
la source
3
  1. Donc, numéro 1 ci-dessus . Qu'est-ce que l'inversion de contrôle?

  2. L'entretien est la première chose qu'il résout pour moi. Cela garantit que j'utilise des interfaces afin que deux classes ne soient pas intimes l'une avec l'autre.

En utilisant un conteneur comme Castle Windsor, il résout encore mieux les problèmes de maintenance. Pouvoir échanger un composant qui va dans une base de données contre un composant qui utilise la persistance basée sur les fichiers sans changer une ligne de code est génial (changement de configuration, vous avez terminé).

Et une fois que vous entrez dans les génériques, c'est encore mieux. Imaginez avoir un éditeur de messages qui reçoit des enregistrements et publie des messages. Peu importe ce qu'il publie, mais il a besoin d'un mappeur pour prendre quelque chose d'un enregistrement à un message.

public class MessagePublisher<RECORD,MESSAGE>
{
    public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo)
    {
      //setup
    }
}

Je l'ai écrit une fois, mais maintenant je peux injecter de nombreux types dans cet ensemble de code si je publie différents types de messages. Je peux également écrire des mappeurs qui prennent un enregistrement du même type et les mappent à différents messages. L'utilisation de DI avec des génériques m'a donné la possibilité d'écrire très peu de code pour accomplir de nombreuses tâches.

Oh oui, il y a des problèmes de testabilité, mais ils sont secondaires par rapport aux avantages de l'IoC / DI.

J'adore vraiment l'IoC / DI.

3. Il devient plus approprié dès que vous avez un projet de taille moyenne, un peu plus complexe. Je dirais que cela devient approprié dès que vous ressentez de la douleur.

ferventcoder
la source
3

La création d'un objet au sein d'une classe est appelée couplage étroit, Spring supprime cette dépendance en suivant un modèle de conception (DI / IOC). Dans quel objet de classe est passé dans constructeur plutôt que de créer en classe. De plus, nous donnons une variable de référence de super classe dans le constructeur pour définir une structure plus générale.

shA.t
la source