PHP-Inversion der Kontrolle und Abhängigkeitsinjektion

PHPz
Freigeben: 2023-03-06 15:08:01
Original
1589 Leute haben es durchsucht

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 &#39;b&#39;;
	}
}

class C
{
	public function C()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;c&#39;;
	}
}

$a=new A();
$a->Method();

?>
Nach dem Login kopieren

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();
	} 
}
Nach dem Login kopieren

Client-Klasse Schreiben Sie so:


$a=new A(new B(),new C());
$a->Method();
Nach dem Login kopieren

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 &#39;b&#39;;
	}
}
class B1 extends B
{
	public function B1()
	{
		//TODO
	}
	public function Method()
	{
		echo &#39;b1&#39;;
	}
}
class B2 extends B
{
	public function B2()
	{
		//TODO
	}
	public function Method()
	{
		echo &#39;b2&#39;;
	}
}
Nach dem Login kopieren

Das ist es Auch sehr einfach. Die Client-Klasse ist so geschrieben:


$a=new A(new B2(),new C());
$a->Method();
Nach dem Login kopieren

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 &#39;B&#39;:
			{
				return new B();
				break;
			}
			case &#39;C&#39;:
			{
				return new C();
				break;
			}
			default:
			{
				return null;
				break;
			}
		}
	}
}
Nach dem Login kopieren

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(&#39;B&#39;);
		$this->c=$f->create(&#39;C&#39;);
		
		$this->b->Method();
		$this->c->Method();
		
		//TODO
	} 
}
Nach dem Login kopieren

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();
}
Nach dem Login kopieren

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 &#39;b&#39;;
	}
}

class C implements IMethod
{
	public function C()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;c&#39;;
	}
}
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage