Prinzip der Abhängigkeitsinversion
Definition
A. Module der oberen Ebene sollten nicht von Modulen der unteren Ebene abhängen. Beide Modultypen müssen von Abstraktionen abhängen.
B. Abstraktionen sollten nicht von Details abhängen. Die Details sollten von der Abstraktion abhängen.
Die erste Definition beinhaltet das Konzept des "Moduls". Dies ist ein sehr wichtiges Konzept, ohne das DIP nicht verstanden werden kann.
Modul - ein logisch miteinander verbundener Satz von Funktionselementen
Um Missverständnisse zu vermeiden, betrachten Sie die Definitionen anhand eines Beispiels. Angenommen, wir müssen eine Liste der gelesenen Bücher abrufen und sie dem Benutzer anzeigen. Dazu verwenden wir die Klassen BooksInteractor und BooksRepository. Wir setzen jede dieser Klassen in das Modul BI bzw. BR ein. Das BooksInteractor-Klassenmodul hängt von der BooksRepository-Klasse ab.
BooksInteractor'y muss eine Liste der Bücher von BooksRepository erhalten. Dem Interactor ist es egal, wie das Repository diese Daten empfängt. In diesem Fall ist BooksInteractor eine Abstraktion für BooksRepository. Gemäß der zweiten Definition sollte BooksInteractor (Abstraktion) NICHT von BooksRepository (Implementierung) abhängen. Andererseits sollte das Repository über das BI-Modul Bescheid wissen. Was passiert also: Der Interaktor muss sich im Repository befinden? Nein, um die Abhängigkeiten zu invertieren, müssen wir nur das BooksRepository mit der IBooksRepository-Schnittstelle abdecken und diese Schnittstelle in das Modul der BooksInteractor-Klasse einfügen. Kehren wir nun zur ersten Definition von DIP zurück und sehen uns das Diagramm an.
Schauen Sie, die übergeordneten Module (BI-Modul) hängen nicht von den untergeordneten Modulen (BR-Modul) ab. Und beide Module hängen von der Abstraktion ab (von der IBooksRepository-Schnittstelle). Wenn Sie die Magie der Abhängigkeitsinversion erkannt haben, indem Sie ein Repository mit einer Schnittstelle abgedeckt haben, verstehen Sie das Prinzip der Abhängigkeitsinversion. Herzliche Glückwünsche! Der schwierigste Teil, den Sie verstehen. Sie können mehr über DIP in diesem Artikel über Habré lesen .
Umkehrung der Kontrolle
Wir haben das Konzept des "Dependency Inversion Principle" untersucht. Kommen wir nun zu einer anderen Umkehrung - der Umkehrung der Kontrolle. Das Konzept selbst ist sehr weit gefasst und kann bei der Programmierung eines von drei Dingen bedeuten:
- Inversion von Schnittstellen - Delegation der Beziehung zwischen Modulen an eine Zwischenschnittstelle. Wo gilt es? Zum Beispiel im DIP, das wir zuvor untersucht haben.
- — (, DI/IOC ).
- — , . , , — Android . Activity Fragment, .
Dependency Injection
Die Abhängigkeitsinjektion ist ein Mechanismus zum Übergeben seiner Abhängigkeiten an eine Klasse. Sie stoßen immer dann darauf, wenn Sie eine Abhängigkeit an eine andere Klasse übergeben müssen. Es gibt verschiedene Möglichkeiten, Abhängigkeiten einzufügen: über einen Konstruktor (Constructor Injection), über eine Methode (Method Injection) und über eine Eigenschaft (Property Injection). Jede dieser Methoden wird für ihre eigenen Zwecke verwendet. Hier ist es jedoch wichtig zu verstehen, dass Dependency Injection nur eine Abhängigkeit an einen Konstruktor, eine Methode oder eine Eigenschaft übergibt.
Randfälle berücksichtigen
- Könnte es DI ohne IoC und DIP geben? Ja vielleicht. Wir erstellen eine Instanz einer konkreten Klasse A und übergeben sie über einen Konstruktor, eine Methode oder eine Eigenschaft an ein Objekt der Klasse B.
- Könnte es DIP ohne IoC geben? Nein, DIP ist eine Möglichkeit, die Schnittstelleninversion in IoC zu implementieren.
- Könnte es ein DIP ohne DI geben? Ja, wir können die unteren Module an die Schnittstelle binden. Die oberen Modulklassen arbeiten mit der Schnittstellenabstraktion, die konkrete Implementierung der unteren Modulklasse wird jedoch im Konstruktor des oberen Moduls erstellt.
Hier und hier können Sie die Unterschiede zwischen DIP, DI und IoC anderer Autoren herausfinden .
Ich würde mich über Ihre Kommentare und Rückmeldungen freuen!