L'inversion de contrôle est un principe de conception générique de l'architecture logicielle qui permet de créer des cadres logiciels réutilisables, modulaires et faciles à maintenir.
Il s'agit d'un principe de conception dans lequel le flux de contrôle est "reçu" de la bibliothèque écrite de manière générique ou du code réutilisable.
Pour mieux comprendre, voyons comment nous codions dans nos premiers jours de codage. Dans les langages procéduraux/traditionnels, la logique métier contrôle généralement le flux de l'application et "appelle" le code/fonctions génériques ou réutilisables. Par exemple, dans une simple application Console, mon flux de contrôle est contrôlé par les instructions de mon programme, qui peuvent inclure les appels à certaines fonctions générales réutilisables.
print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);
//More print and scan statements
<Do Something Interesting>
//Call a Library function to find the age (common code)
print Age
En revanche, avec IoC, les cadres sont le code réutilisable qui "appelle" la logique métier.
Par exemple, dans un système basé sur Windows, un cadre sera déjà disponible pour créer des éléments d'interface utilisateur tels que des boutons, des menus, des fenêtres et des boîtes de dialogue. Lorsque j'écris la logique métier de mon application, ce sont les événements du framework qui appellent mon code de logique métier (lorsqu'un événement est déclenché) et NON l'inverse.
Bien que le code du framework ne connaisse pas ma logique métier, il saura quand même comment appeler mon code. Ceci est réalisé en utilisant des événements/délégués, des callbacks, etc. Ici, le contrôle du flux est "inversé".
Ainsi, au lieu de faire dépendre le flux de contrôle d'objets liés statiquement, le flux dépend du graphe d'objets global et des relations entre les différents objets.
L'injection de dépendances est un modèle de conception qui met en œuvre le principe IoC pour résoudre les dépendances des objets.
En termes plus simples, lorsque vous essayez d'écrire du code, vous allez créer et utiliser différentes classes. Une classe (classe A) peut utiliser d'autres classes (classe B et/ou D). Ainsi, les classes B et D sont des dépendances de la classe A.
Une analogie simple sera une voiture de classe. Une voiture peut dépendre d'autres classes comme le moteur, les pneus, etc.
L'injection de dépendances suggère qu'au lieu que la classe dépendante (ici la classe Car) crée ses dépendances (classe Engine et classe Tyre), la classe devrait être injectée avec l'instance concrète de la dépendance.
Comprenons avec un exemple plus pratique. Considérons que vous êtes en train d'écrire votre propre TextEditor. Entre autres choses, vous pouvez avoir un correcteur orthographique qui permet à l'utilisateur de vérifier les fautes de frappe dans son texte. Une implémentation simple d'un tel code peut être :
Class TextEditor
{
//Lot of rocket science to create the Editor goes here
EnglishSpellChecker objSpellCheck;
String text;
public void TextEditor()
{
objSpellCheck = new EnglishSpellChecker();
}
public ArrayList <typos> CheckSpellings()
{
//return Typos;
}
}
À première vue, tout semble rose. L'utilisateur va écrire un texte. Le développeur capturera le texte et appellera la fonction CheckSpellings et trouvera une liste de coquilles qu'il montrera à l'utilisateur.
Tout semble fonctionner parfaitement jusqu'au jour où un utilisateur commence à écrire en français dans l'éditeur.
Pour fournir le support pour plus de langues, nous devons avoir plus de correcteurs orthographiques. Probablement le français, l'allemand, l'espagnol, etc.
Ici, nous avons créé un code étroitement couplé avec le correcteur d'orthographe "anglais" qui est étroitement couplé avec notre classe TextEditor, ce qui signifie que notre classe TextEditor est dépendante du correcteur d'orthographe "anglais" ou en d'autres termes, le correcteur d'orthographe "anglais" est la dépendance de TextEditor. Nous devons supprimer cette dépendance. De plus, notre éditeur de texte a besoin d'un moyen de tenir la référence concrète de n'importe quel vérificateur d'orthographe basé sur la discrétion du développeur au moment de l'exécution.
Ainsi, comme nous l'avons vu dans l'introduction de DI, il suggère que la classe soit injectée avec ses dépendances. Ainsi, il devrait être de la responsabilité du code appelant d'injecter toutes les dépendances à la classe/code appelé. Nous pouvons donc restructurer notre code comme suit
interface ISpellChecker
{
Arraylist<typos> CheckSpelling(string Text);
}
Class EnglishSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
Class FrenchSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
Dans notre exemple, la classe TextEditor doit recevoir l'instance concrète du type ISpellChecker.
Maintenant, la dépendance peut être injectée dans un constructeur, une propriété publique ou une méthode.
Essayons de modifier notre classe en utilisant Constructor DI. La classe TextEditor modifiée ressemblera à quelque chose comme ça :
Class TextEditor
{
ISpellChecker objSpellChecker;
string Text;
public void TextEditor(ISpellChecker objSC)
{
objSpellChecker = objSC;
}
public ArrayList <typos> CheckSpellings()
{
return objSpellChecker.CheckSpelling();
}
}
Ainsi, le code appelant, lors de la création de l'éditeur de texte, peut injecter le type de correcteur orthographique approprié à l'instance du TextEditor.
Vous pouvez lire l'article complet ici
0 votes
Duplication possible de Qu'est-ce que l'inversion de contrôle ?
4 votes
@SteveChambers ce n'est pas un doublon, cette question est posée dans la perspective des sources. Cette question est posée en perspective générale.
0 votes
stackoverflow.com/questions/57386896/