Dependency Injection Container Understanding
Kopplung
Ein guter Codestrukturentwurf muss lose gekoppelt sein, was auch der Zweck vieler gängiger Entwurfsmuster ist. Es besteht darin, die überall verstreuten Codes derselben Funktion zu einem Modul zusammenzuführen und dann über einige kleine und klare Kanäle zwischen verschiedenen Modulen zu kommunizieren.
In der Praxis ist die gegenseitige Abhängigkeit zwischen verschiedenen Funktionen und Modulen unvermeidlich, und der Umgang mit der Beziehung zwischen diesen Abhängigkeiten ist der Schlüssel dafür, ob die Codestruktur schön werden kann.
<?php class User { public function register($user) { // 注册操作 ... // 发送确认邮件 $notify = new Notify(); $notify->sendEmail('register', $user); } } class Notify { public function sendEmail($type, $data) { switch $type { case 'register': // 发送注册确认邮件 $email = new Email($type); $email->send($data); ... } } } class Email { public function send($data) { // 发送邮件 } }
Im obigen Code gibt es Schicht-für-Schicht-Abhängigkeiten zwischen den drei Klassen. Die Reihenfolge der Instanziierung ist Benutzer -> E-Mail
Das Das heißt, ich instanziiere zuerst. Die Benutzerklasse führt möglicherweise Code aus und instanziiert dann andere Klassen, die ich benötige, z. B. Notify usw.
Diese Art von Abhängigkeit zwingt uns dazu, einige Vorbereitungsarbeiten durchzuführen, um die erforderlichen Abhängigkeiten zu erhalten. Manchmal reicht ein neuer Vorgang möglicherweise nicht aus. Dieser Teil der Arbeit wird als Kopplung bezeichnet und zwingt eine Klasse mit unabhängigen Funktionen, sich um einige Operationen zu kümmern, die nichts mit ihrer Hauptfunktion zu tun haben.
Entfernen der Abhängigkeit einer Klasse von anderen Klassen
Es ist auch sehr einfach, dieses Problem zu lösen: Ich kann zuerst die E-Mail-Klasse instanziieren, dann Notify instanziieren und dann das E-Mail-Objekt als übergeben ein Parameter Um zu benachrichtigen, instanziieren Sie schließlich die Benutzerklasse und übergeben Sie dann Notify. Dies ist die sogenannte Abhängigkeitsinjektion. Sie können sehen, dass die Reihenfolge der Klasseninstanziierung in diesem Prozess vollständig umgekehrt ist. Das abhängige Objekt wird zuerst instanziiert und nicht das endgültige erforderliche Objekt.
Der Code lautet wie folgt:
<?php $email = new Email(); $notify = new Notify($email); $user = new User($notify);
Sie können die erforderlichen Abhängigkeiten über den Konstruktor einfügen oder andere Methoden verwenden.
Verwenden Sie einen Container, um Abhängigkeiten zu hosten
Dann gibt es ein neues Problem. Im Beispiel gibt es nur drei Klassen, die von Notify to abhängig sind Wenn ich E-Mails sende, speichert das Abhängigkeitsmodell die Datenbank und verlässt sich beim Caching auf Redis. Obwohl dadurch die Abhängigkeit außerhalb der Klasse übertragen wird, muss ich immer noch viel manuelle Vorbereitungsarbeit leisten, wenn ich nur den Benutzer instanziieren möchte, was den Code verwirrend macht . Daher wird zu diesem Zeitpunkt ein Container benötigt. Die Rolle dieses Containers besteht darin, diese Abhängigkeiten für mich zu verwalten.
<?php // 容器 class Container implements ArrayAccess { protected $values = []; public function offsetGet($offset) { return $this->values[$offset]($this); } public function offsetSet($offset, $value) { $this->values[$offset] = $value; } }
Wenn das Programm startet, können wir eine Reihe grundlegender Dienste an einem Ort registrieren.
<?php $container = new Container(); $container['notify'] = function($c) { return new Notify(); }; $container['email'] = function($c) { return new Email(); };
wird wie folgt aussehen: Das heißt, wenn der Benutzer Notify benötigt, fragt er den Container nach einem Objekt dieser Klasse. Was Notify sonst noch betrifft, weiß ich nicht Sie müssen sich darüber keine Sorgen machen, da Notify den Container auch nach den benötigten Abhängigkeiten fragt. Die Verarbeitung all dieser Abhängigkeiten wird vollständig vom Container verwaltet. Wir müssen uns weder um die hierarchische Beziehung zwischen Abhängigkeiten kümmern noch die Kopplung zwischen Abhängigkeiten vermeiden. Es ist zu beachten, dass der Abhängigkeitsinjektionscontainer im Allgemeinen nur eine anonyme Funktion und kein instanziiertes Objekt akzeptiert. Die anonyme Funktion teilt dem Container mit, wie ein Objekt abgerufen werden kann, sodass ein Dienst bei Bedarf verwendet werden kann wird nur instanziiert, wenn Das obige ist der detaillierte Inhalt vonLeicht verständlicher PHP-Abhängigkeitsinjektionscontainer. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!<?php
class User
{
public function register($user)
{
// 注册操作
...
// 发送确认邮件
$container('notify')->sendEmail('register', $user);
}
}
class Notify
{
public function sendEmail($type, $data)
{
switch $type {
case 'register':
// 发送注册确认邮件
$email = $container['email'];
$email->send($data);
...
}
}
}
class Email
{
public function send($data)
{
// 发送邮件
}
}