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'; } }
Um ein paar Punkte zusammenzufassen:
1 Wir verlagern die Erstellung von Klasse-B-Objekten und Klasse-C-Objekten in Klasse A 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 hängt von B und C ab.
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Beispielcodes von PHP Inversion of Control (IOC) und Dependency Injection (DI). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!