依存性注入コンテナの理解
結合
優れたコード構造設計は疎結合である必要があり、これは多くの一般的な設計パターンの目的でもあります。どこにでも散在する同じ機能のコードを集めてモジュールを形成し、いくつかの小さくて明確なチャネルを通じて異なるモジュール間で通信することです。
実際には、異なる関数やモジュール間の相互依存関係は避けられず、これらの依存関係の関係をどのように処理するかが、コード構造を美しくできるかどうかの鍵となります。
<?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) { // 发送邮件 } }
上記のコードでは、3 つのクラス間にレイヤーごとの依存関係があります。3 つのクラスのインスタンス化の順序は、ユーザー -> 通知 -> 電子メール
です。つまり、最初にインスタンスを作成します。User クラスはコードを実行してから、Notify などの必要な他のクラスをインスタンス化します。
この種の依存関係では、必要な依存関係を取得するためにいくつかの準備作業を行う必要があります。場合によっては、新しい操作では不十分な場合があります。この部分の作業はカップリングと呼ばれ、独立した関数を持つクラスに、そのメイン関数とは関係のない一部の操作を強制します。
あるクラスの他のクラスへの依存関係を削除する
この問題を解決するのも非常に簡単で、最初に Email クラスをインスタンス化し、次に Notify をインスタンス化し、次に Email オブジェクトを次のように渡すことができます。 Notify するには、最後に User クラスをインスタンス化し、Notify を渡します。これはいわゆる依存関係の注入です。このプロセスでのクラスのインスタンス化の順序が完全に逆になっていることがわかります。最終的に必要なオブジェクトが最初にインスタンス化されるのではなく、依存オブジェクトが最初にインスタンス化されます。これは制御の反転です。
コードは次のとおりです:
<?php $email = new Email(); $notify = new Notify($email); $user = new User($notify);
コンストラクターを通じて必要な依存関係を注入することも、他のメソッドを使用することもできます。
コンテナを使用して依存関係をホストする
次に、新しい問題が発生します。この例には 3 つのクラスしかありませんが、User クラスが電子メールの送信に Notify に依存しているとします。 , これは Model がデータベースを保存し、redis にキャッシュに依存することに依存します。これにより依存関係がクラスの外に転送されますが、User をインスタンス化するだけの場合は依然として多くの手動準備作業が必要となり、コードが混乱します。したがって、現時点ではコンテナが必要です。このコンテナの役割は、これらの依存関係を管理することです。
<?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; } }
プログラムを開始すると、一連の基本サービスを 1 か所に登録できます。
<?php $container = new Container(); $container['notify'] = function($c) { return new Notify(); }; $container['email'] = function($c) { return new Email(); };
これは次のようになります つまり、ユーザーが Notify を必要とするとき、ユーザーはコンテナにこのクラスのオブジェクトを要求します。Notify が他にどのようなものに依存するかについては、私は知りません。 Notify はコンテナーに必要な依存関係も要求するため、心配する必要はありません。これらすべての依存関係の処理はコンテナーによって完全に管理されるため、依存関係間の階層関係を気にしたり、依存関係間の結合を回避したりする必要はありません。 依存関係注入コンテナーは通常、インスタンス化されたオブジェクトではなく、匿名関数のみを受け入れることに注意してください。匿名関数は、必要なときにサービスを使用できるように、コンテナーにオブジェクトの取得方法を指示します。 <?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)
{
// 发送邮件
}
}
以上が理解しやすいPHP依存関係注入コンテナの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。