Dependency Injection
クラス A がクラス B に依存する必要がある場合、つまりクラス B をインスタンス化する必要がある場合クラスA内 オブジェクトを使用する際、クラスBの機能が変更されると、クラスA内でクラスBが使用されている箇所も変更され、クラスAとクラスBの間の結合度が高くなります。現時点での解決策は、クラス A がクラス B のインターフェースに依存し、特定のクラスのインスタンス化を外部に渡すことです。
私たちのビジネスで一般的に使用されている通知モジュールを考えてみましょう。
<?php /** * 定义了一个消息类 * Class Message */ class Message{ public function seed() { return '灰太狼准备吃羊'; } } /* * 订单产生的时候 需要发送消息 */ class Order{ protected $messager = ''; function __construct() { $this->messager = new Message(); } public function seed_msg() { return $this->messager->seed(); } } $Order = new Order(); echo $Order->seed_msg();
上記のコードは、従来の書き方です。まず、メッセージで送信されるクラスです。次に、メッセージを送信する必要がある場合は、メッセージを送信するためのインターフェイスを呼び出します。ある日、さまざまなニーズを満たすためにテキスト メッセージを送信するためのインターフェイスを追加する必要が生じます。次に、Message クラスを変更する必要があることがわかります。 Order クラスも変更する必要があります。これはとても面倒そうです。このとき、依存性注入というアイデアが生まれました。
<?php /** * 为了约束我们先定义一个消息接口 * Interface Message */ interface Message{ public function seed(); } /** * 有一个发送邮件的类 * Class SeedEmail */ class SeedEmail implements Message { public function seed() { return '灰太狼发邮件给红太狼说要吃烤全羊'; } } /** *新增一个发送短信的类 * Class SeedSMS */ class SeedSMS implements Message { public function seed() { return '灰太狼发短信给红太狼说要吃烤全羊'; } } /* * 订单产生的时候 需要发送消息 */ class Order{ protected $messager = ''; function __construct(Message $message) { $this->messager = $message; } public function seed_msg() { return $this->messager->seed(); } } //我们需要发送邮件的时候 $message = new SeedEmail(); //将邮件发送对象作为参数传递给Order $Order = new Order($message); echo $Order->seed_msg(); echo "\n"; //我们需要发送短信的时候 $message = new SeedSMS(); $Order = new Order($message); echo $Order->seed_msg();
私が理解しているサービスコンテナとは、クラスを自動生成するファクトリのことです。
<?php /** * 为了约束我们先定义一个消息接口 * Interface Message */ interface Message{ public function seed(); } /** * 有一个发送邮件的类 * Class SeedEmail */ class SeedEmail implements Message { public function seed() { return '灰太狼发邮件给红太狼说要吃烤全羊'; } } /** *新增一个发送短信的类 * Class SeedSMS */ class SeedSMS implements Message { public function seed() { return '灰太狼发短信给红太狼说要吃烤全羊'; } } /** * 这是一个简单的服务容器 * Class Container */ class Container { protected $binds; protected $instances; public function bind($abstract, $concrete) { if ($concrete instanceof Closure) { $this->binds[$abstract] = $concrete; } else { $this->instances[$abstract] = $concrete; } } public function make($abstract, $parameters = []) { if (isset($this->instances[$abstract])) { return $this->instances[$abstract]; } array_unshift($parameters, $this); return call_user_func_array($this->binds[$abstract], $parameters); } } //创建一个消息工厂 $message = new Container(); //将发送短信注册绑定到工厂里面 $message->bind('SMS',function (){ return new SeedSMS(); }); //将发送邮件注册绑定到工厂 $message->bind('EMAIL',function (){ return new SeedEmail(); }); //需要发送短信的时候 $SMS = $message->make('SMS'); echo $SMS->seed(); echo "\n"; $EMAIL = $message->make('EMAIL'); echo $EMAIL->seed();
コンテナは、bind,makeTwo を備えた単純なサービス コンテナです。 Methods
bind は、サービス オブジェクトをコンテナーにバインドします。
make はコンテナからオブジェクトを取り出します。
bind メソッドでは、具体的なオブジェクトを渡す必要があり、インスタンス オブジェクトまたはクロージャ関数を渡すことができます。
クロージャ関数を使用していることがわかります。実際、このように書くこともできます
$sms = new SeedSMS(); $message->bind('SMS',$sms);
この後者の書き方とクロージャの違いは、オブジェクトをインスタンス化してからインスタンス化する必要があることです。簡単に進めることができます。このサービスを使用する場合、クロージャはオブジェクトのみをインスタンス化します。クロージャーには多くの利点があることがわかります。
make メソッドはコンテナを終了するメソッドです。まず、インスタンス変数に現在および既存のサービス オブジェクトがあるかどうかを判断し、存在する場合はそれを直接返します。そうでない場合は、call_user_func_array を通じてオブジェクトが返されます。 call_user_func_array の使用については、
PHP
PHP 関連の技術記事の詳細については、PHP チュートリアル を参照してください。 学びのコラム!
以上がPHP でのサービス コンテナーと依存関係注入の関連分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。