Es kommt meistens auf Kopplung des Codes.
class Foo {
public function __construct() {
new Bar;
}
}
Diese Paare eine sehr spezifische Bar
auf diese spezifische Foo
. Es gibt keine Möglichkeit zu ändern , dieBar
wird instanziiert, ohne diesen Code neu zu schreiben. Das bedeutet auch, dass Foo
über die Abhängigkeiten von Bar
informiert werden muss. Vielleicht kann heute Bar
mit nur new Bar
instanziiert werden. Aber vielleicht morgen refaktorieren Sie Bar
und müssen es jetzt mit new Bar($database)
instanziieren. Jetzt müssen Sie auch Foo
umschreiben, um das unterzubringen.
Das ist, wo Dependency Injection kommt in (der oben ist nicht Dependency Injection, du bist nicht etwas Injektion):
class Foo {
public function __construct(Bar $bar) { }
}
Diese Foo
lediglich erklärt, dass sie ein Objekt mit den Eigenschaften benötigt Bar
nach Instanziierung. Aber Foo
muss nichts darüber wissen, wie Bar
kam, was seine Abhängigkeiten sind oder was genau es tut. Das einzige, was es von Bar
erwartet, ist eine definierte public
Schnittstelle, alles andere ist irrelevant. Um noch mehr Flexibilität zu erhalten, sollten Sie statt einer konkreten Klassenabhängigkeit hier eine interface
verwenden.
Mit der Abhängigkeitsinjektion können Sie konkrete Details von Klassen von anderem Code trennen. Sie können einen zentralen Ort verwenden, an dem Klassen instanziiert werden. Dies ist ein Ort, an dem Sie konkrete Details zu den Klassen, die Sie instanziieren, kennen und berücksichtigen müssen. Dies kann beispielsweise ein Abhängigkeitsinjektionscontainer sein. Sie möchten die Klasseninstanziierungslogik nicht überall verbreiten, denn wie oben erwähnt, kann sich diese Logik ändern, und dann müssen Sie den Code überall neu schreiben.
require_once 'Foo.php';
require_once 'Bar.php';
$foo = new Foo(new Bar);
Der obige Code ist, wo es entschieden wird, die Bar
in Foo
injiziert wird. Es ist auch der Ort, der sich um die Abhängigkeiten von Bar
kümmern muss. Beachten Sie, dass das Laden und Instanziieren von Abhängigkeiten das einzige ist, was dieser Code tut. Es ist trivial, nur dieses Stück Code wie erforderlich zu ändern, ohne Foo
oder Bar
zu berühren, die voller komplexer Geschäftslogik sein können.
Dependency injected Code ermöglicht es Ihnen auch, Ihre App auseinander zu nehmen und sie flexibel zusammenzustellen. Zum Beispiel für Testzwecke. Oder einfach um verschiedene Komponenten flexibel in verschiedenen Kontexten wiederzuverwenden.
Siehe auch How Not To Kill Your Testability Using Statics.
Das erste Beispiel ist sehr schwer zu testen, weil Sie Foo in Bar nicht verspotten können; Die zweite heißt Dependency Injection (DI) und erlaubt es Ihnen, Foo zu verspotten, wenn Sie Bar –
mögliche Duplikate von [Was ist Dependency-Injektion?] (http://stackoverflow.com/questions/130794/what-is- Abhängigkeitsinjektion) – Gal
Die zweite eliminiert auch die Notwendigkeit, dass Foo tatsächlich eine Foo-Instanz ist, aber erlaubt es entweder ein Foo oder eine Instanz einer Klasse zu sein, die Foo erweitert (der Typhinweis erzwingt das) .... lose Kopplung , weil Sie nicht mehr auf einen tatsächlichen Foo beschränkt sind. –