In diesem Artikel werden hauptsächlich Beispiele für PHP-Kontrollinversion und Abhängigkeitsinjektion vorgestellt. Der Zweck der Abhängigkeitsinjektion besteht darin, eine lose gekoppelte Softwarearchitektur für besseres Testen, Verwalten und Erweitern von Code zu erreichen.
Kontrollumkehr : Wenn der Anrufer die Hilfe des Angerufenen benötigt, erstellt der Anrufer im herkömmlichen Programmierprozess normalerweise die Instanz des Angerufenen, hier jedoch die Die Arbeit zur Erstellung des Angerufenen wird nicht mehr vom Aufrufer durchgeführt, sondern die Erstellung des Angerufenen wird außerhalb des Aufrufers verlagert, wodurch die Erstellung des Angerufenen rückgängig gemacht und der Aufruf eliminiert wird. Die vom Aufrufer über den Angerufenen geschaffene Kontrolle wird daher als Umkehrung von bezeichnet Kontrolle.
Abhängigkeitsinjektion : Um eine Umkehrung der Kontrolle zu erreichen, besteht die übliche Lösung darin, die Arbeit zum Erstellen der aufgerufenen Instanz dem IoC-Container zu überlassen und sie dann in den Aufrufer zu injizieren (durch implementiert). Konstruktor-/Methodeninjektion), damit wir eine Entkopplung des Aufrufers und des Aufgerufenen erreichen, wird dieser Prozess als Abhängigkeitsinjektion bezeichnet. Die Abhängigkeitsinjektion ist eine Implementierung der Umkehrung der Kontrolle. Es gibt drei gängige Injektionsmethoden: Setter-, Konstruktor-Injektion und Eigenschaftsinjektion.
Container (Container) : Verwaltet den Lebenszyklus der Objektgenerierung, Ressourcenbeschaffung, Zerstörung usw., stellt Abhängigkeiten zwischen Objekten her und kann das Laden von Objekten verzögern. Die bekannteren sind PHP-DI und Pimple.
Codedemonstration IoC:
Gehen Sie davon aus, dass die Anwendung Speicheranforderungen hat. Wenn die Low-Level-Modul-API direkt in der High-Level-Anwendung aufgerufen wird, Die Anwendung erstellt Module Abhängigkeiten.
<?php /** * 高层 */ class App { private $writer; public function __construct() { $this->writer = new FloppyWriter(); } public function save() { $this->writer->saveToFloppy(); } } /** * 低层,软盘存储 */ class FloppyWriter { public function saveToFloppy() { echo __METHOD__; } } $app = new App(); $app->save(); // FloppyWriter::saveToFloppy
Angenommen, das Programm soll auf eine andere Plattform portiert werden und diese Plattform verwendet einen USB-Datenträger als Speichermedium, dann kann das Programm nicht direkt wiederverwendet werden und muss geändert werden. In diesem Fall folgen aufgrund von Änderungen auf niedriger Ebene auch Änderungen auf hoher Ebene, was ein schlechtes Design darstellt. Programme sollten nicht auf konkreten Implementierungen, sondern auf abstrakten Schnittstellen basieren. Bitte sehen Sie sich die Codedemonstration an:
<?php /** * 接口 */ interface IDeviceWriter { public function saveToDevice(); } /** * 高层 */ class App { /** * @var IDeviceWriter */ private $writer; /** * @param IDeviceWriter $writer */ public function setWriter($writer) { $this->writer = $writer; } public function save() { $this->writer->saveToDevice(); } } /** * 低层,软盘存储 */ class FloppyWriter implements IDeviceWriter { public function saveToDevice() { echo __METHOD__; } } /** * 低层,USB盘存储 */ class UsbDiskWriter implements IDeviceWriter { public function saveToDevice() { echo __METHOD__; } } $app = new App(); $app->setWriter(new UsbDiskWriter()); $app->save(); // UsbDiskWriter::saveToDevice $app->setWriter(new FloppyWriter()); $app->save(); // FloppyWriter::saveToDevice
Die Steuerung wird vom eigentlichen FloppyWriter auf die abstrakte IDeviceWriter-Schnittstelle übertragen, wodurch die App von der IDeviceWriter-Schnittstelle abhängig wird und FloppyWriter und UsbDiskWriter ebenfalls von der IDeviceWriter-Schnittstelle abhängig sind.
Dies ist IoC. Angesichts von Änderungen muss die hohe Ebene keine Codezeile ändern und verlässt sich nicht mehr auf die untere Ebene, sondern auf die Injektion, was zu DI führt.
Wenn diese Komponente viele Abhängigkeiten aufweist, müssen wir mehrere Parametersettermethoden erstellen, um Abhängigkeiten zu übergeben, was die Wartung unseres Codes erschwert.
<?php //创建依赖实例 $request = new Request(); $filter = new Filter(); //把实例作为参数传递给构造函数 $some = new SomeComponent($request, $filter); $some->setRequest($request); $some->setFilter($filter);
Die Lösung besteht darin, einen Container für die abhängige Instanz bereitzustellen. Dieser Container fungiert als globale Registrierung, die in den Container und nicht in die spezifische Instanz eingefügt wird.
<?php class SomeComponent { protected $_di; public function __construct($di) { $this->_di = $di; } public function someRequest() { // 请求实例 $connection = $this->_di->get('request'); } public function someOtherRequest() { // 请求实例 $connection = $this->_di->get('request'); // 过滤器实例 $filter = $this->_di->get('filter'); } } $di = new DI(); //在容器中注册一个request服务 $di->set('request', function() { return new Request(array( "test" => "test" )); }); //在容器中注册一个filter服务 $di->set('filter', function() { return new Filter(); }); //把传递服务的容器作为唯一参数传递给组件 $some = new SomeComponent($di); $some->someRequest();
Diese Komponente kann jetzt problemlos die Dienste abrufen, die sie benötigt. Der Dienst verwendet Lazy Loading und wird nur bei Bedarf initialisiert, was auch Serverressourcen spart. Diese Komponente ist nun stark entkoppelt.
Verwandte Empfehlungen:
Analyse der PHP-Abhängigkeitsinjektion und Inversion der Kontrolle
PHP-Abhängigkeitsinjektion (DI) und Inversion der Kontrolle (IoC) Beispiel Tutorials
PHP Inversion of Control und Dependency Injection
Das obige ist der detaillierte Inhalt vonBeispiele für PHP-Inversion der Kontrolle und Abhängigkeitsinjektion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!