Verständnis von IoC, DI und Referenzmethoden

8

Ich bin dabei, Depenency-Injektion und Inversion der Kontrolle zu lernen, und ich glaube, ich beginne zu verstehen, wie das funktioniert:

  • Objekte sollten sich nicht mit der Erstellung eigener Abhängigkeiten beschäftigen
  • Abhängigkeiten sollten an das Objekt übergeben werden (über die Konstruktor- oder Setter-Methoden)
  • Ein DI-Container kann Objekte mit allen erforderlichen Abhängigkeiten erstellen

Wenn das alles korrekt ist, kann ich nicht mehr das verwenden, was ich "Referenzmethoden" in meinen Objekten nenne?

Hier ist was ich mit Referenzmethoden meine. Sagen wir, ich habe zwei Modelle für Familien und Familienmitglieder. Ich finde es sehr hilfreich, Methoden zu erstellen, die auf Objekte verweisen, die sich auf dieses Modell beziehen. Im folgenden Beispiel kann ich bei Aufruf von $family->members() schnell auf alle Familienmitglieder zugreifen. Aber das würde bedeuten, dass mein family -Objekt family_member -Klassen instanziiert ... und bricht dies nicht die Regeln von IoC?

Was wäre, wenn die Klasse family_member eine Abhängigkeit hätte, die außerhalb des Bereichs der Klasse family liegt? Eingabe hier wäre sehr geschätzt!

%Vor%     
Jonathan 24.10.2011, 20:11
quelle

3 Antworten

5

Disclaimer: Ich lerne gerade DI selbst. Nehmen Sie die Antwort mit einem Körnchen Salz.

Abhängigkeitsinjektion ist nur ungefähr Abhängigkeiten injizieren . Wenn Ihr objektorientiertes Design dazu führt, dass Family -Objekt Instanzen von Member erstellen muss, dann muss das Family -Objekt unbedingt Member erstellen, da in diesem Fall Member wird nicht länger als eine Abhängigkeit von Family betrachtet, sondern als Verantwortung . Deshalb:

%Vor%

Aber wenn Sie darüber nachdenken, sollte Family wirklich dafür verantwortlich sein, Member zu erstellen? Ein besseres Design ist ein anderes Objekt, zB FamilyMapper create Family zusammen mit seinen Mitgliedern. So:

%Vor%

Mit diesem Muster werden Ihre Domänenobjekte zusammen mit ihren Methoden (die Geschäftslogik enthalten können) von Ihrem Datenzugriffscode entkoppelt. Das ist das Gute an der Abhängigkeitsinjektion - es zwingt Sie dazu, Ihr OO-Design zu überdenken, damit Sie saubereren Code erhalten.

Viele Leute denken, dass die Verwendung von Abhängigkeitsinjektionen bedeutet, dass keine Fabriken und dergleichen verwendet werden. Das ist falsch! Die Abhängigkeitsinjektion erfolgt nur über Abhängigkeiten injizieren . Sie können die Abhängigkeitsinjektion auch für Factory-Objekte verwenden, indem Sie Abhängigkeiten in die Factory einfügen, anstatt dass die Factory ihre eigene Abhängigkeit instanziiert.

Nützliche Links:

  1. Ссылка
  2. Hat jemand eine gute Analogie für die Abhängigkeitsinjektion?
  3. Wie die Abhängigkeitsinjektion zu einem 5- Jahre alt?

Zusätze

Nimm das Zeug hier unten mit einem Körnchen Salz.

Bitte beachten Sie auch, dass es einen Unterschied zwischen Abhängigkeitsinjektion und Abhängigkeitsinjektionscontainer gibt. Die erste ist ein einfaches Konzept, Abhängigkeiten zu injizieren, anstatt Objekte selbst zu erzeugen (was zu einer sehr hohen Kopplung führt). Wir sehen das aus dem obigen Beispiel.

Letzteres ist ein Begriff für Frameworks / Bibliotheken, die sich mit der Abhängigkeitsinjektion befassen, so dass Sie keine manuelle Injektion durchführen müssen. Die Verantwortung des Containers liegt in den Verdrahtungsabhängigkeiten, so dass Sie die schmutzige Arbeit nicht erledigen müssen. Die Idee besteht darin, define eine Dependency-Injection-Konfiguration zu definieren, die dem Container mitteilt, welche Abhängigkeiten Foo object hat und wie sie injiziert werden. Der Container liest die Dokumentation und führt die Injektion für Sie durch. Dies ist, was DIC-Bibliotheken wie Pimple, SimpleDIC tun.

Sie können Dependency-Injection-Container mit Factories vergleichen, da beide Creation-Objekte sind, deren Aufgabe es ist, Objekte zu erstellen. Während Fabriken oft spezialisiert sind (d. H.% Co_de% erzeugt Instanzen von FamilyMemberFactory ), ist der Container für die Abhängigkeitsinjektion allgemeiner. Einige Leute sagen, die Verwendung von Dependency-Injection-Containern entbindet Sie von der Notwendigkeit von Factories, aber Sie sollten daran denken, dass Sie Dependency-Injection-Konfigurationsdateien erstellen und verwalten müssen, die Tausende von XML / PHP-Zeilen enthalten können.

Ich hoffe, das hilft.

    
rickchristie 25.10.2011, 07:22
quelle
1

Sie können zwar nur mit der Abhängigkeitsinjektion arbeiten und versuchen, eine Balance in Ihrem Design zu finden und es gleichzeitig wartbar zu halten, ist meiner Meinung nach jedoch ein vernünftigerer Ansatz.

Als solche wird eine Kombination aus Abhängigkeitsinjektion und Fabriken Ihr Leben viel einfacher machen.

%Vor%

Das Fabrikmuster ist etwas kompatibel mit Inversion der Kontrolle und Abhängigkeitsinjektion. Während die Abhängigkeitsinjektion Ihr Objekt davon befreit, Abhängigkeiten zu erzeugen, kann das Factory-Muster eine Basisimplementierung einer Abhängigkeit erzeugen. Und am Ende können Sie Objektabhängigkeiten bei Bedarf noch überschreiben:

%Vor%

Dies ist besonders nützlich beim Testen:

%Vor%

Abhängigkeitsinjektion ist großartig, aber es kann nicht alle Ihre Konstruktionsprobleme lösen. Natürlich sind sie nicht austauschbar. Das Fabrikmuster kann Dinge nicht tun und umgekehrt.

    
netcoder 24.10.2011 20:55
quelle
0

Das Problem ist, dass die ganze Idee hinter DI ist, dass Family nicht wissen sollte, wie man ein bestimmtes FamilyMember erstellt, zum Beispiel sollten Sie ein IFamilyMember haben und Implementierungen dafür können auf jedem Modul / Layer variieren Ihrer Anwendung.

Sollte etwa so aussehen:

%Vor%

Im Grunde genommen entspricht alles der Idee, dass Komponenten Ignoranten ihrer Abhängigkeiten sein sollten, und in Ihrem Fall hängt Family von FamilyMember ab, sodass jede FamilyMember Implementierung von der Familie selbst abstrahiert werden muss.

Für den speziellen Fall von PHP sollten Sie Symfony ausprobieren, das das DI-Muster stark nutzt, oder Sie können es in Erwägung ziehen das Symfony Dependency Injection-Framework , das ein Teil von Symfony ist, aber als separate Komponente verwendet werden kann. Auch Fabien Potencier hat einen schönen Artikel zu diesem Thema geschrieben.

Ich hoffe, ich kann helfen!

    
David Conde 24.10.2011 20:37
quelle