Da die Abhängigkeitsinjektion die Kopplung zwischen der Abhängigkeit und dem abhängigen Typ verringert, ist es beim Ändern der abhängigen Typimplementierung nicht erforderlich, gleichzeitig die abhängige Typimplementierung zu ändern Verwendung für abhängige Typtests „Mocking Object“ ersetzt den ursprünglichen abhängigen Typ, um den Zweck des unabhängigen Unit-Tests abhängiger Objekte zu erreichen.
0. Einführung
Im Bereich der Softwareentwicklung wird die Abhängigkeitsinjektion (Dependency Injection) zur Implementierung verwendet Kontrollrückmeldung Eine der gebräuchlichsten Methoden der Kontrollumkehr. In diesem Artikel werden hauptsächlich die Prinzipien und gängigen Implementierungsmethoden der Abhängigkeitsinjektion vorgestellt, wobei der Schwerpunkt auf den anwendbaren Szenarien und Vorteilen dieses jungen Entwurfsmusters liegt.
1. Warum ist eine Abhängigkeitsinjektion erforderlich?
Wer entkoppelt sich? Dies war die erste Frage, die ich hatte, als ich zum ersten Mal etwas über die Abhängigkeitsinjektion erfuhr.
Im Folgenden zitiere ich einen Teil des Codes, den Martin Flower zur Erläuterung der Injektion verwendet hat, um dieses Problem zu veranschaulichen.
public class MovieLister { private MovieFinder finder; public MovieLister() { finder = new MovieFinderImpl(); } public Movie[] moviesDirectedBy(String arg) { List allMovies = finder.findAll(); for (Iterator it = allMovies.iterator(); it.hasNext();) { Movie movie = (Movie) it.next(); if (!movie.getDirector().equals(arg)) it.remove(); } return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]); } ... }
public interface MovieFinder { List findAll(); }
Wir haben eine Klasse namens MovieLister erstellt, um die erforderliche Filmliste bereitzustellen, und ihre moviesDirectedBy-Methode bietet eine Möglichkeit, nach Filmen basierend auf Regisseurnamen zu suchen. Was wirklich für die Suche nach Filmen verantwortlich ist, ist MovieFinderImpl, das die MovieFinder-Schnittstelle implementiert. Unsere MovieLister-Klasse erstellt ein MovieFinderImpl-Objekt im Konstruktor.
Bis jetzt sieht alles gut aus. Wenn wir jedoch den Finder ändern und durch eine neue Implementierung ersetzen möchten (z. B. das Hinzufügen eines Parameters zu MovieFinder, um anzugeben, aus welcher Datenbank die Filmdaten stammen), müssen wir nicht nur die MovieFinderImpl-Klasse ändern, sondern auch Ändern Sie das in unserem MovieLister-Code erstellte MovieFinderImpl.
Dies ist die Kopplung, mit der sich die Abhängigkeitsinjektion befasst. Durch diese Art der Erstellung von MovieFinderImpl in MovieLister ist MovieLister nicht nur auf die MovieFinder-Schnittstelle angewiesen, sondern auch auf die Implementierung von MovieListImpl. Diese Art von Code, der Objekte einer anderen Klasse direkt in einer Klasse erstellt, wie z. B. fest codierte Zeichenfolgen und fest codierte Zahlen (magische Zahlen), ist ein schlechter Geruch, der zur Kopplung führt. Wir können diesen schlechten Geruch als harte Init bezeichnen . Gleichzeitig sollten wir uns ebenso wie hartes Codieren daran erinnern, dass Neues (Objekterstellung) giftig ist.
Die Hauptnachteile von Hard Init sind zwei Aspekte: 1) Wenn Sie die Implementierung wie oben erwähnt ändern, müssen Sie den Code dort ändern, wo er erstellt wurde. 2) Es ist nicht einfach zu testen, und die Klassen sind nicht einfach Der auf diese Weise erstellte (oben) MovieLister in diesem Artikel) kann nicht alleine getestet werden und sein Verhalten ist eng mit MovieFinderImpl verknüpft. Gleichzeitig führt dies auch zu Problemen bei der Lesbarkeit des Codes („Wenn ein Code nicht einfach zu testen ist , dann muss es nicht leicht lesbar sein.")
2. So implementieren Sie die Abhängigkeitsinjektion
Abhängigkeitsinjektion wird in vielen unserer täglichen Codes verwendet, aber wir bemerken sie selten. und nutzen die Abhängigkeitsinjektion selten aktiv zur Entkopplung. Hier stellen wir kurz die drei Methoden vor, mit denen man sich auf die Injektion verlassen kann.
2.1 Konstruktorinjektion
Dies ist meiner Meinung nach die einfachste Abhängigkeitsinjektionsmethode. Ändern wir den Konstruktor von MovieList im obigen Code, sodass die Implementierung von MovieFinderImpl in der außerhalb erstellten MovieLister-Klasse erfolgt. Auf diese Weise hängt MovieLister nur von der von uns definierten MovieFinder-Schnittstelle ab, nicht von der Implementierung von MovieFinder.
public class MovieLister { private MovieFinder finder; public MovieLister(MovieFinder finder) { this.finder = finder; } ... }
2.2 Setter-Injection
Ähnlich können wir eine Setter-Funktion hinzufügen, um das erstellte MovieFinder-Objekt zu übergeben, wodurch auch eine harte Initialisierung dieses Objekts in MovieFinder vermieden werden kann.
public class MovieLister { s... public void setFinder(MovieFinder finder) { this.finder = finder; } }
2.3 Schnittstelleninjektion
Schnittstelleninjektion verwendet die Schnittstelle, um die Setter-Methode bereitzustellen, und ihre Implementierung ist wie folgt.
Erstellen Sie zunächst eine Schnittstelle für die Injektion.
public interface InjectFinder { void injectFinder(MovieFinder finder); }
Danach lassen wir MovieLister diese Schnittstelle implementieren.
class MovieLister implements InjectFinder { ... public void injectFinder(MovieFinder finder) { this.finder = finder; } ... }
Schließlich müssen wir abhängige MovieFinder-Implementierungen gemäß verschiedenen Frameworks erstellen.
3. Abschließend
Abhängigkeitsinjektion reduziert die Kopplung zwischen Abhängigkeiten und abhängigen Typen. Es besteht keine Notwendigkeit, die Implementierung von zu ändern Gleichzeitig ist es für abhängige Typtests bequemer, den ursprünglichen abhängigen Typ durch ein Spottobjekt zu ersetzen, um den Zweck des unabhängigen Komponententests abhängiger Objekte zu erreichen.
Abschließend sei darauf hingewiesen, dass die Abhängigkeitsinjektion nur eine Möglichkeit ist, die Umkehrung der Kontrolle zu implementieren. Eine weitere gängige Implementierung der Kontrollumkehr ist die sogenannte Abhängigkeitssuche.
Das obige ist der detaillierte Inhalt vonWarum verwendet PHP die Abhängigkeitsinjektion?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!