Il semble y avoir beaucoup de confusion au sujet du modèle d'inversion de contrôle (IoC). Un certain nombre de personnes l'ont assimilé au modèle de stratégie ou à un modèle de composant, mais ces comparaisons ne reflètent pas vraiment en quoi consiste l'IoC. L'IoC concerne vraiment la façon dont une dépendance est obtenue. Laisse moi te donner un exemple:
class Game {
void Load() {
this.Sprite.Load(); // loads resource for drawing later
}
}
class Sprite {
void Load() {
FileReader reader = new FileReader("path/to/resource.gif");
// load image from file
}
}
Dans ce qui précède, il est clair que cela Sprite.Load
dépend de a FileReader
. Pour tester la méthode, vous avez besoin des éléments suivants:
- Un système de fichiers en place
- Un fichier de test à charger depuis le système de fichiers
- Possibilité de déclencher des erreurs de système de fichiers courantes
Les deux premiers sont évidents, mais si vous voulez vous assurer que votre gestion des erreurs fonctionne comme prévu, vous avez vraiment besoin du n ° 3 également. Dans les deux cas, vous avez potentiellement ralenti considérablement vos tests car ils doivent maintenant aller sur le disque et vous avez probablement rendu votre environnement de test plus compliqué.
Le but de l'IoC est de dissocier l'utilisation du comportement de sa construction. Notez en quoi cela diffère du modèle de stratégie. Avec le modèle de stratégie, l'objectif est d'encapsuler un morceau de comportement réutilisable afin que vous puissiez facilement l'étendre à l'avenir; cela n'a rien à dire sur la façon dont les stratégies sont construites.
Si nous devions réécrire la Sprite.Load
méthode ci-dessus, nous finirions probablement par:
class Sprite {
void Load(IReader reader) {
// load image through reader
}
}
Maintenant, nous avons découplé la construction du lecteur de son utilisation. Par conséquent, il est possible d'échanger un lecteur de test pendant le test. Cela signifie que votre environnement de test n'a plus besoin d'un système de fichiers, de fichiers de test et peut facilement simuler des événements d'erreur.
Notez que j'ai fait deux choses dans ma réécriture. J'ai créé une interface IReader
qui a encapsulé un certain comportement - c'est-à-dire implémenté le modèle de stratégie. De plus, j'ai transféré la responsabilité de créer le bon lecteur à une autre classe.
Peut-être que nous n'avons pas besoin d'un nouveau nom de modèle pour décrire ce qui précède. Cela me semble être un mélange des modèles de stratégie et d'usine (pour les conteneurs IoC). Cela étant dit, je ne sais pas pour quelles raisons les gens s'opposent à ce modèle, car il est clair qu'il résout un problème réel, et, certainement, il n'est pas évident pour moi ce que cela a à voir avec Java.