Question

L'inversion de contrôle (ou 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é de l’utiliser et quand non ?
Était-ce utile?

La solution

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

Par exemple, supposons que votre application dispose d'un composant d'édition de texte et que vous souhaitiez fournir 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 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 instancions SpellChecker (this.checker = new SpellChecker();), ce qui signifie que TextEditor la classe dépend directement du SpellChecker classe.

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

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

Maintenant, le client créant le TextEditor la classe a le contrôle sur lequel SpellChecker implémentation à utiliser car nous injectons la dépendance dans le TextEditor signature.

Ceci est juste un exemple simple, il y a une bonne série d'articles de Simone Busoli qui l'explique plus en détail.

Autres conseils

L'inversion de contrôle est ce que vous obtenez lorsque votre programme rappelle, par ex.comme un programme graphique.

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 quelque chose du genre, nous disons à la place :

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 saisies et le moment où les données sont enregistrées dans la base de données.

Essentiellement, rien avec une boucle d'événement, des rappels ou des déclencheurs d'exécution entre dans cette catégorie.

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éparé quoi-partie à faire de quand-partie à faire.
  2. Veiller à ce que quand une partie sait comme petit que possible sur quoi 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.

--

Le inversion une partie de l’inversion du contrôle (IoC) est ce qui prête à confusion ;parce que inversion est le terme relatif.La meilleure façon de comprendre IoC est d’oublier ce mot !

--

Exemples

  • Gestion des événements.Gestionnaires d'événements (partie quoi faire) - Déclenchement d'événements (partie quand faire)
  • Interfaces.Client de composant (partie « quand faire ») -- Implémentation de l'interface de composant (partie « quoi faire »)
  • Luminaire xUnit.Setup et TearDown (partie quoi faire) - Les frameworks xUnit appellent Setup au début et TearDown à la fin (partie quand faire)
  • Modèle de conception de méthode de modèle.méthode modèle partie « quand faire » -- implémentation de sous-classe primitive partie « quoi faire »
  • Méthodes de conteneur DLL dans COM.DllMain, DllCanUnload, etc (partie quoi faire) -- COM/OS (partie quand faire)

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

Sans IoC:Tu as un ordinateur portable ordinateur et vous cassez accidentellement l’écran.Et bon sang, vous constatez que le même modèle d’écran d’ordinateur portable n’est nulle part sur le marché.Donc tu es coincé.

Avec IoC:Tu as un ordinateur de bureau ordinateur et vous cassez accidentellement l’écran.Vous constatez que vous pouvez vous procurer presque n’importe quel moniteur de bureau du marché, et cela fonctionne bien avec votre bureau.

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

L'inversion de contrôle, (ou IoC), concerne obtenir la liberté (Vous vous mariez, vous avez perdu votre liberté et vous êtes contrôlé.Vous avez divorcé, vous venez de mettre en place l’Inversion de Contrôle.C’est ce que nous appelons « découplé ».Un 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 propre du robinet, c'est votre seul choix lorsque vous souhaitez boire.Votre patron a mis en œuvre l'inversion du contrôle en installant une nouvelle machine à café.Vous avez désormais la possibilité de choisir entre l'eau du robinet ou le 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 emploi, 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 disons contrôlé).Il faut s'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 inversez quelque peu le contrôle.Vous pouvez facilement le prendre et vous déplacer.Vous pouvez désormais contrôler où vous vous trouvez avec votre ordinateur, au lieu que ce soit votre ordinateur qui le contrôle.

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

Avec les idées ci-dessus à l’esprit.Il nous manque encore un élément clé d’IoC.Dans le scénario de l’IoC, le consommateur logiciel/objet est un framework 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 doivent construire une voiture.Ces travailleurs ont besoin d'un lieu et d'outils (un cadre logiciel) pour construire la voiture.UN traditionnel le framework logiciel sera comme un garage avec de nombreux outils.Les ouvriers doivent donc élaborer eux-mêmes un plan et utiliser les outils pour construire la voiture.Construire une voiture n’est pas une tâche facile, il sera très difficile pour les ouvriers de planifier et de coopérer correctement.UN moderne Le cadre logiciel sera comme une usine automobile moderne avec toutes les installations et tous les gestionnaires en place.Les travailleurs n'ont pas besoin d'élaborer de plan, les managers (qui font partie du cadre, ce sont les personnes les plus intelligentes et qui ont élaboré le plan le plus sophistiqué) aideront à se coordonner afin que les travailleurs sachent quand faire leur travail (le cadre appelle votre code).Les travailleurs doivent juste être suffisamment flexibles pour utiliser tous les outils que les managers leur mettent à disposition (en utilisant l'injection de dépendances).

Bien que les ouvriers donnent le contrôle de la gestion du projet au plus haut niveau aux managers (le framework).Mais c'est bien d'avoir l'aide de quelques professionnels.C’est de là que vient réellement le concept d’IoC.

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

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

Avant d'utiliser l'Inversion de Contrôle, vous devez être bien conscient du fait qu'elle présente des avantages et des 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 les implémentations d'une interface avec des implémentations alternatives
  • C'est une forte motivation pour coder sur des interfaces plutôt que sur des 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/setter et vous pouvez facilement les initialiser avec les bons objets de manière isolée.

Les inconvénients:

  • IoC inverse non seulement le flux de contrôle dans votre programme, mais il le brouille également considérablement.Cela signifie que vous ne pouvez plus simplement lire votre code et passer 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 ou les annotations XML et dans le code de votre conteneur IoC qui interprète ces métadonnées.
  • Il apparaît une nouvelle classe de bugs où vous vous trompez dans votre configuration XML ou dans vos 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 d'IoC et je les aime beaucoup mais j'ai tendance à éviter IoC autant que possible car il transforme votre logiciel en un ensemble de classes qui ne constituent plus un "vrai" programme mais juste quelque chose qui doit être mis en place par Les métadonnées de configuration ou d'annotation XML s'effondreraient (et s'effondreraient) sans elles.

  1. Article Wikipédia.Pour moi, l'inversion du contrôle consiste à transformer votre code écrit séquentiellement en une structure de délégation.Au lieu que votre programme contrôle tout explicitement, votre programme configure une classe ou une bibliothèque avec certaines fonctions à appeler lorsque certaines choses se produisent.

  2. Cela résout la duplication de code.Par exemple, autrefois, vous écriviez manuellement votre propre boucle d'événements, en interrogeant les bibliothèques système pour détecter de nouveaux événements.De nos jours, la plupart des API modernes indiquent simplement aux bibliothèques système les événements qui vous intéressent, et elles vous informeront 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 résoudre ce problème 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 bruts.

    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 au cœur de votre propre programme à moins qu'elle ne résolve réellement un problème de duplication de code.

Mais je pense qu'il faut y faire très attention.Si vous abusez de ce modèle, vous créerez une conception très compliquée et un code encore plus compliqué.

Comme dans cet exemple avec TextEditor :si vous n'avez qu'un seul SpellChecker, 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 du genre...

De toute façon:être raisonnable.Les modèles de conception sont bonnes pratiques mais pas la Bible à prêcher.Ne le collez pas partout.

Supposons que vous soyez un objet.Et tu vas au restaurant :

Sans IoC:vous demandez "pomme", et on vous sert toujours une pomme lorsque 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 pastèque.

Alors évidemment, l’IoC est à privilégier lorsqu’on aime les variétés.

Pour moi, IoC/DI pousse les dépendances vers les objets appelants.Hyper simple.

La réponse non technique est de pouvoir remplacer le moteur d'une voiture juste avant de l'allumer.Si tout se connecte correctement (l’interface), tout va bien.

  1. L'inversion de contrôle est un modèle utilisé pour découpler les composants et les couches du 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 comme interfaces pour un découplage plus poussé 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 de l'IoC.Ces outils fournissent des fonctionnalités étendues au-delà de la simple gestion des dépendances, notamment la durée de vie, l'AOP/interception, la politique, etc.

  2. un.Permet à un composant d'être responsable de la gestion de ses dépendances.
    b.Offre la possibilité d’échanger les implémentations de dépendances dans différents environnements.
    c.Permet de tester un composant en simulant les dépendances.
    d.Fournit un mécanisme de partage de ressources dans une application.

  3. un.Critique lors du développement piloté par les tests.Sans IoC, les tests peuvent être difficiles à réaliser, 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 résolues, en particulier dans une application d’entreprise.

J'écrirai ma simple compréhension de ces deux termes :

For quick understanding just read examples*

Injection de dépendances (DI) :
L'injection de dépendance signifie généralement passer un objet dont dépend la méthode, en tant que paramètre d'une méthode, plutôt que de laisser la méthode créer l'objet dépendant.
Cela signifie en pratique 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, indiquez 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 cadres, CIO gère les objets Java
– de l’instanciation à la destruction grâce à sa BeanFactory.
-Les composants Java instanciés par le conteneur IoC sont appelés beans, et le Le conteneur IoC gère la portée d'un bean, les événements du cycle de vie et toutes les fonctionnalités AOP pour lequel 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 l'inversion de contrôle, un consommateur de logiciel/objet obtient plus de contrôles/options sur le logiciel/objets, au lieu d'être contrôlé ou d'avoir moins d'options.

L'inversion du contrôle en tant que ligne directrice de conception répond aux objectifs suivants :

Il existe un découplage entre l'exécution d'une certaine tâche et sa 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 garderai 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

Répondant uniquement à la première partie.Qu'est-ce que c'est?

L'inversion de contrôle (IoC) signifie créer des instances de dépendances en premier et en dernière instance d'une classe (en les injectant éventuellement via un constructeur), au lieu de créer d'abord une instance de la classe, puis l'instance de classe créant des instances de dépendances.Ainsi, l’inversion du contrôle inverse le flux de contrôle du programme. Au lieu de le appelé contrôlant le flux de contrôle (lors de la création de dépendances), le l'appelant contrôle le flux de contrôle du programme.

Par exemple, la tâche n°1 consiste à créer un objet.Sans le 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 le conteneur.

En bref, le contrôle est inversé du programmeur au conteneur.C’est ce qu’on appelle l’inversion du contrôle.

J'ai trouvé un bon exemple ici.

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

Beaucoup de monde, 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 comme ça, nous avons un sol recouvert de gobelets en plastique et d'eau.

Laissez inverser le contrôle.

La même réunion au même endroit, mais à la place des gobelets en plastique nous avons un serveur avec un gobelet en verre (Singleton)

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

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

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

Et c'est exactement ce que fait Spring (un autre conteneur IoC, par exemple :Guice) le fait.Au lieu de laisser l'application créer ce dont elle a besoin à l'aide d'un nouveau mot-clé (prendre un gobelet en plastique), le conteneur Spring IoC propose toujours à 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 d'envoyer un message à l'administration de l'hôtel :

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:-

je suis d'accord avec ObjetNul, mais j'aimerais ajouter à ceci :

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 une inversion de contrôle

Si vous copiez et collez du code, vous faites presque toujours quelque chose faux.Codifié comme principe de conception Une et une seule fois.

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

Avons-nous vraiment besoin d’un nom pour décrire la différence entre la programmation procédurale et événementielle ?OK, 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 ?

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

  • Dans le développement logiciel normal, vous écrivez le principal() méthode et appelez les méthodes "bibliothèque". Toi sont en contrôle :)
  • Dans IoC, le "framework" contrôle principal() et appelle vos méthodes.Le Cadre est en contrôle :(

DI (Dependency Injection) concerne la façon dont le contrôle se déroule 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 framework s'occupe du démarrage de votre application, de son initialisation et de l'appel de vos méthodes chaque fois que nécessaire.

Au final, tu gagnes toujours :)

Inversion de 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 réussi 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, la rendant plus flexible.

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 demande non triviale comprend deux ou plusieurs classes qui collaborer les uns avec les autres pour exécuter une certaine logique d'affaires.Traditionnellement, chaque objet est responsable de l'obtention de son propre les références aux objets avec lesquels il collabore (ses dépendances).Lors de l'application de DI, les objets reçoivent leurs dépendances à la création temps 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."

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-à-direla 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 considérant l’inversion du contrôle comme un modèle de conception, nous devons examiner ce que nous inversons.L'injection de dépendances inverse le contrôle de la construction d'un graphe d'objets.En termes simples, l'inversion du contrôle implique un changement dans le flux de contrôle dans le programme.Par exemple.Dans une application autonome traditionnelle, nous avons la méthode principale, à partir de laquelle le contrôle est transmis à d'autres bibliothèques tierces (au cas où nous aurions utilisé la fonction d'une bibliothèque tierce), mais grâce à l'inversion du contrôle, le contrôle est transféré du code de la bibliothèque tierce à notre code. , car nous utilisons le service d'une bibliothèque tierce.Mais il y a d'autres aspects qui doivent être inversés au sein d'un programme - par ex.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 des 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) = Injection de dépendance (état) + Injection de continuation + Injection de thread

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

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

Code classique (sans injection de dépendances)

Voici comment fonctionnera grossièrement un code n’utilisant pas DI :

  • L'application nécessite Foo (par ex.un contrôleur), donc :
  • L'application crée Foo
  • L'application appelle Foo
    • Foo a besoin de Bar (par ex.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

Utiliser l'injection de dépendances

Voici comment fonctionnera grossièrement 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 celle appelée à celle 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 rend les tests beaucoup plus faciles.

Ex:Supposons que votre application stocke le fichier téléchargé par l'utilisateur dans Google Drive. Avec DI, le code de votre 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, il vous est demandé d'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 le test, vous pouvez créer la simulation pour StorageServiceInterface avec l'implémentation factice où toutes les méthodes renvoient null (ou toute valeur prédéfinie selon vos besoins de test).

Au lieu de cela, si vous aviez la classe contrôleur pour construire l'objet de stockage avec le new mot-clé comme celui-ci :

class SomeController
{
    private $storage;

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

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

Lorsque vous souhaitez modifier l'implémentation de Dropbox, vous devez remplacer toutes les lignes où new L'objet GoogleDriveService est construit et utilise DropboxService.De plus, 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.

Programmation parlant

IoC en termes simples :Il s'agit de l'utilisation de l'interface comme moyen de quelque chose de spécifique (comme un champ ou un paramètre) comme 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 Service pour chiens et Service de chat, je peux en créer un seul appelé ServiceAnimal qui permet d'utiliser Chien et Chat uniquement s'ils utilisent l'interface IAnimal.

Cependant, d’un point de vue pragmatique, il y a quelques revers.

un) La plupart des développeurs ne savent pas comment l'utiliser.Par exemple, je peux créer une classe appelée Client et Je peux créer automatiquement (en utilisant les outils de l'EDI) une interface appelée IClient.Il n'est donc pas rare de trouver un dossier rempli de classes et d'interfaces, peu importe si les interfaces seront réutilisées ou non.C'est ce qu'on appelle BLOATED.Certaines personnes pourraient affirmer que "nous pourrions peut-être l'utiliser dans le futur".:-|

b) Cela présente certaines limites.Parlons par exemple du cas de Chien et Chat et je souhaite ajouter un nouveau service (fonctionnalité) uniquement pour les chiens.Disons que je souhaite calculer le nombre de jours dont j'ai besoin pour dresser un chien (trainDays()), pour les chats ça ne sert à rien, les chats ne peuvent pas être dressés (je plaisante).

b.1) Si j'ajoute trainDays() au service ServiceAnimal alors ça marche aussi avec les chats et ce n'est pas valable du tout.

b.2) Je peux ajouter une condition dans trainDays() où il évalue quelle classe est utilisée.Mais cela briserait complètement l’IoC.

b.3) Je peux créer une nouvelle classe de service appelée Service pour chiens 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 Chien et c'est mauvais.

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

Il commence simplement et montre également des exemples de code.

enter image description here

Le consommateur, X, a besoin de la classe consommée, Y, pour accomplir quelque chose.Tout cela est bien et naturel, mais X a-t-il vraiment besoin de savoir qu’il utilise Y ?

N'est-il 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 ce 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 en utiliser une instance au lieu de Y, il peut continuer à faire ce qu'il fait sans avoir à connaître les détails de Y.

enter image description here

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 encore Y, ce qui est intéressant c’est que X ne le sait pas.Il sait simplement 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 au moment de l'exécution
  • Isolation de l'unité de code, tests plus faciles

...

Je comprends que la réponse a déjà été donnée ici.Mais je pense toujours que certaines bases sur l’inversion du contrôle doivent être discutées ici en détail pour les futurs lecteurs.

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

Ne nous appelez pas, nous vous appellerons

Cela signifie que n'allez pas à Hollywood pour réaliser votre rêve, mais si vous en êtes digne, Hollywood vous trouvera et réalisera votre rêve.Plutôt inversé, hein ?

Maintenant, lorsque nous discutons du principe de l’IoC, nous avions l’habitude d’oublier 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ésenter un cadre générique (peut être écrit par vous ou quelqu'un d'autre), toi représente le code utilisateur que vous avez écrit et la tâche représentez la chose que vous voulez accomplir avec votre code.Désormais, vous n'allez plus jamais déclencher votre tâche par vous-même, pas dans IoC !Au contraire, vous avez tout conçu de telle sorte que votre cadre déclenchera votre tâche à votre place.Ainsi, vous avez construit un cadre réutilisable qui peut faire de quelqu'un un héros ou d'un autre un méchant.Mais ce cadre est toujours aux commandes, il sait quand choisir quelqu'un et ce quelqu'un sait seulement 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 doit gérer, comme la gestion des requêtes http, la création du menu de l'application, la diffusion des pages, la gestion des cookies, le déclenchement d'événements, etc.

Et puis vous laissez quelques crochets dans votre framework où vous pouvez mettre des codes supplémentaires pour générer un menu personnalisé, des pages, des cookies ou enregistrer certains événements utilisateur, etc.À chaque requête du navigateur, votre framework s'exécutera et exécutera vos codes personnalisés s'il est connecté, puis les renverra au navigateur.

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

Laravel et EJB sont des exemples de tels frameworks.

Référence:

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

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

L'inversion de 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 (transmet) 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 véhiculent un comportement) dans les bibliothèques peut également être considéré comme IoC.

  1. Donc numéro 1 au-dessus de. Qu’est-ce que l’inversion de contrôle ?

  2. La maintenance est la première chose que cela 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, cela résout encore mieux les problèmes de maintenance.Pouvoir remplacer un composant qui va dans une base de données contre un autre qui utilise la persistance basée sur des fichiers sans changer une ligne de code est génial (changement de configuration, vous avez terminé).

Et une fois que l’on se lance dans les génériques, c’est encore mieux.Imaginez avoir un éditeur de messages qui reçoit des enregistrements et publie des messages.Il ne se soucie pas de ce qu'il publie, mais il a besoin d'un mappeur pour transformer quelque chose d'un enregistrement en message.

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

Je l'ai écrit une fois, mais je peux désormais 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.Utiliser DI avec Generics 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 IoC/DI.

3 .Cela devient plus approprié à partir du moment où vous avez un projet de taille moyenne et un peu plus complexe.Je dirais que cela devient approprié dès que vous commencez à ressentir de la douleur.

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 le 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.

En utilisant IoC, vous ne renouvellez pas vos objets.Votre conteneur IoC fera cela et gérera leur durée de vie.

Cela résout le problème de devoir changer manuellement chaque instanciation d’un type d’objet à un autre.

Cela est approprié lorsque vous disposez de fonctionnalités qui peuvent changer dans le futur ou qui peuvent être différentes en fonction de l'environnement ou de la configuration utilisée.

Pour comprendre le concept, l'inversion de contrôle (IoC) ou le principe d'inversion de dépendance (DIP) implique deux activités :abstraction et inversion.L'injection de dépendances (DI) n'est que l'une des rares méthodes d'inversion.

Pour en savoir plus à ce sujet, vous pouvez lire mon blog Ici

  1. Qu'est-ce que c'est?

C'est une pratique où vous laissez le comportement réel venir de l'extérieur des limites (Classe en programmation orientée objet).L'entité frontière n'en connaît que l'abstraction (par exemple interface, classe abstraite, délégué en programmation orientée objet).

  1. Quels problèmes cela résout-il ?

En termes de programmation, IoC essaie de résoudre le code monolithique en le rendant modulaire, en dissociant diverses parties et en le rendant testable unitairement.

  1. Quand est-ce approprié et quand non ?

C'est approprié la plupart du temps, sauf si vous avez une situation où vous voulez juste du code monolithique (par exemple un programme très simple)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top