2015-09-29 3 views
7

Ich versuche, Abhängigkeitsinjektion in PHP zu verstehen, und ich sehe, es gibt zwei Möglichkeiten, dies in Laravel zu tun.Was ist der Unterschied zwischen diesen beiden Arten von Konstruktorinjektionen in PHP?

Also lassen Sie uns sagen, ich habe eine Klasse Foo wie so:

class Foo{ 

} 

Jetzt habe ich eine Klasse namens Bar, die auf Foo abhängig ist, so konnte ich so etwas tun:

class Bar{ 
    protected $foo; 
    public function __construct() 
    { 
     $this->foo = new Foo(); 
    } 
} 

Aber in Laravel habe ich Begriffe wie Typhinweisen und Spiegelungen gefunden, die mir erlauben, dies zu tun:

class Bar{ 
    protected $foo; 
    public function __construct(Foo $foo) 
    { 
     $this->foo = $foo; 
    } 
} 

Was ich versuche zu verstehen, ist der Unterschied zwischen diesen beiden. Sind sie völlig identisch? Und gibt es einen bestimmten Grund, warum ich dem anderen vorziehen sollte?

PS: Ich bin Neuling und ich bin mir nicht sicher, ob ich den Jargon in der Frage richtig verwende.

+9

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 –

+3

mögliche Duplikate von [Was ist Dependency-Injektion?] (http://stackoverflow.com/questions/130794/what-is- Abhängigkeitsinjektion) – Gal

+5

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

Antwort

1

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.

+0

Vielen Dank für diese detaillierte Antwort. Ich schätze es. :) – Rohan

Verwandte Themen