Schauen wir uns zunächst ein Beispiel an:
<?php class A { public $b; public $c; public function A() { //TODO } public function Method() { $this->b=new B(); $this->c=new C(); $this->b->Method(); $this->c->Method(); //TODO } } class B { public function B() { //TODO } public function Method() { //TODO echo 'b'; } } class C { public function C() { //TODO } public function Method() { //TODO echo 'c'; } } $a=new A(); $a->Method(); ?>
Mit dem obigen Code können wir einen Satz leicht verstehen:
Klasse A Abhängig vonKlasse B und Klasse C
Das heißt, wenn im zukünftigen Entwicklungsprozess Klasse B oder Klasse C geändert werden muss, sobald die Funktion wird umbenannt, Wenn sich die Anzahl der Funktionsparameter ändert oder sogar die gesamte Klassenstruktur angepasst wird, müssen wir entsprechende Anpassungen an Klasse A vornehmen. Die Unabhängigkeit von Klasse A geht verloren, was sehr ist Dies ist während des Entwicklungsprozesses unbequem, d. . .
Wenn wir die Kategorien B und C wirklich ändern müssen, gibt es dann eine Möglichkeit, den Code der Kategorie A nicht oder so wenig wie möglich zu ändern? Hier kommt die Umkehrung der Steuerung zum Einsatz.
High-Level-Module sollten nicht von Low-Level-Modulen abhängen, beide sollten auf Abstraktionen basieren.
Inversion of Control (IOC) ist eine Idee, und Dependency Injection (DI) ist eine Methode zur Umsetzung dieser Idee.
Die erste Methode heißt: Konstruktorinjektion (diese Methode wird nicht empfohlen, ist aber besser, als sie nicht zu verwenden)
class A { public $b; public $c; public function A($b,$c) { $this->b=$b; $this->c=$c; } public function Method() { $this->b->Method(); $this->c->Method(); } }
Client-Klasse Schreiben Sie so:
$a=new A(new B(),new C()); $a->Method();
Der Konstruktor der Klasse A hängt von der Klasse B und der Klasse C ab. Es wird über die Parameter des Konstruktors übergeben erreicht ist, das heißt, Klasse BObjektDie Erstellung von Objekt b und C, Objekt c, wurde außerhalb von Klasse A verschoben, sodass Klasse A nicht geändert werden muss, sobald Klasse B und Klasse C geändert werden. Ändern Sie es einfach in der Client-Klasse
Angenommen, wir müssen eines Tages Klasse B erweitern und zwei Unterklassen von Klasse B erstellen
class B { public function B() { //TODO } public function Method() { //TODO echo 'b'; } } class B1 extends B { public function B1() { //TODO } public function Method() { echo 'b1'; } } class B2 extends B { public function B2() { //TODO } public function Method() { echo 'b2'; } }
Das ist es Auch sehr einfach. Die Client-Klasse ist so geschrieben:
$a=new A(new B2(),new C()); $a->Method();
Klasse A muss sich also nicht darum kümmern, welche Unterklassen Klasse B hat über die Client-Klasse.
Die zweite Methode heißt: WerksmusterInjektion (empfohlen)
class Factory { public function Factory() { //TODO } public function create($s) { switch($s) { case 'B': { return new B(); break; } case 'C': { return new C(); break; } default: { return null; break; } } } }
Unser Klasse-A-Code wird geändert in:
class A { public $b; public $c; public function A() { //TODO } public function Method() { $f=new Factory(); $this->b=$f->create('B'); $this->c=$f->create('C'); $this->b->Method(); $this->c->Method(); //TODO } }
hat tatsächlich einen kleinen Teil entkoppelt, zumindest wenn sich der Konstruktor von Klasse B und Klasse C ändert, beispielsweise durch Ändern der Funktionsparameter usw., wir müssen nur die Factory-Klasse ändern.
Abstraktion sollte nicht von Details abhängen, Details sollten von der Abstraktion abhängen.
Abstrahieren Sie die Methoden in den Klassen B und C und erstellen Sie eine Schnittstelle
interface IMethod { public function Method(); }
wie diese, das $ bvariable und $c-Variable in Klasse A sind keine konkreten Variablen mehr, sondern Variablen vom Typ abstrakte Klasse. Bis zu dem Moment, in dem sie ausgeführt werden, weiß man nicht, wie ihre Methode implementiert wird.
class B implements IMethod { public function B() { //TODO } public function Method() { //TODO echo 'b'; } } class C implements IMethod { public function C() { //TODO } public function Method() { //TODO echo 'c'; } }
Zusammenfassung Mehrere Punkte:
1 Wir unterteilen die Objekte der Klasse B und der Klasse C in Klasse A. Verschieben Sie die Erstellung außerhalb von Klasse A
2. Ursprünglich stützte sich Klasse A auf Klasse B und Klasse C, aber jetzt hängt A von Factory ab und Factory von B und C.
Das obige ist der detaillierte Inhalt vonPHP-Inversion der Kontrolle und Abhängigkeitsinjektion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!