Es scheint viel Verwirrung über das Inversion-of-Control-Muster (IoC) zu geben. Einige Leute haben es mit dem Strategiemuster oder einem Komponentenmodell gleichgesetzt, aber dieser Vergleich erfasst nicht wirklich, worum es bei IoC geht. Bei IoC geht es wirklich darum, wie eine Abhängigkeit hergestellt wird. Lassen Sie mich Ihnen ein Beispiel geben:
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
}
}
Oben ist klar, dass Sprite.Load
es eine Abhängigkeit von a gibt FileReader
. Wenn Sie die Methode testen möchten, benötigen Sie Folgendes:
- Ein vorhandenes Dateisystem
- Eine Testdatei, die aus dem Dateisystem geladen werden soll
- Möglichkeit, allgemeine Dateisystemfehler auszulösen
Die ersten beiden sind offensichtlich, aber wenn Sie sicherstellen möchten, dass Ihre Fehlerbehandlung wie erwartet funktioniert, brauchen Sie auch wirklich # 3. In beiden Fällen haben Sie Ihre Tests möglicherweise erheblich verlangsamt, da sie jetzt auf Festplatte gespeichert werden müssen, und Sie haben wahrscheinlich Ihre Testumgebung komplizierter gemacht.
Ziel von IoC ist es, den Gebrauch von Verhalten von seiner Konstruktion zu entkoppeln. Beachten Sie, wie sich dies vom Strategiemuster unterscheidet. Mit dem Strategiemuster soll ein wiederverwendbarer Teil des Verhaltens eingekapselt werden, damit Sie es in Zukunft problemlos erweitern können. Es gibt nichts darüber zu sagen, wie Strategien aufgebaut sind.
Wenn wir die Sprite.Load
obige Methode umschreiben würden, hätten wir wahrscheinlich folgendes Ergebnis:
class Sprite {
void Load(IReader reader) {
// load image through reader
}
}
Jetzt haben wir die Konstruktion des Lesegeräts von seiner Verwendung entkoppelt. Daher ist es möglich, während des Testens einen Testleser einzutauschen. Dies bedeutet, dass Ihre Testumgebung kein Dateisystem und keine Testdateien mehr benötigt und problemlos Fehlerereignisse simulieren kann.
Beachten Sie, dass ich beim Umschreiben zwei Dinge getan habe. Ich habe eine Schnittstelle erstellt, die ein IReader
gewisses Verhalten abbildet - dh das Strategiemuster implementiert. Außerdem habe ich die Verantwortung für die Erstellung des richtigen Lesers in eine andere Klasse verlagert.
Vielleicht brauchen wir keinen neuen Musternamen, um das oben Gesagte zu beschreiben. Es erscheint mir als eine Mischung aus Strategie- und Factory-Mustern (für IoC-Container). Abgesehen davon bin ich mir nicht sicher, aus welchen Gründen die Leute gegen dieses Muster Einwände erheben, da klar ist, dass es ein echtes Problem löst, und mir ist sicherlich nicht klar, was dies mit Java zu tun hat.