ホームページ >バックエンド開発 >PHPチュートリアル >PHPでの依存関係の注入と制御の反転
DI - 依存関係の注入
IoC - 制御の反転
上記 2 つの概念を理解するには、次の質問を理解する必要があります:
1. 参加者は誰ですか?
答え: 通常、3 つのパーティがあり、1 つはオブジェクト、もう 1 つはオブジェクトの外部リソースです。名詞についてもう一度説明します。オブジェクトは通常の Java オブジェクトを指します。IoC/DI コンテナは、単に IoC/DI 機能を実装するために使用されるフレームワーク プログラムを指します。オブジェクトの外部リソースは必要ですが、取得されます。オブジェクトの外部からのリソースは、オブジェクトが必要とする他のオブジェクトや、オブジェクトが必要とするファイル リソースなど、総称してリソースと呼ばれます。
2. 依存:誰が誰に依存しているのか?なぜ依存関係があるのでしょうか?
答え: オブジェクトは IoC/DI コンテナに依存します。プロジェクトでは、さまざまなクラス間にさまざまな関係があり、すべてが完全に独立していることは不可能であり、依存関係が形成されます。従来の開発では、他のクラスを使用するときに直接呼び出しますが、これは強い結合を形成するため、避けるべきです。依存関係の注入では、コンテナーを借用して依存オブジェクトを転送し、分離を実現します。
3. 注射:誰が誰に注射するのか?いったい何が注入されるのでしょうか?
答え: 必要な外部リソースをコンテナを通じてオブジェクトに注入します
4. 制御の反転: 誰が誰を制御するのか?何を制御しますか?なぜ逆転と呼ばれるのでしょうか?
回答: IoC/DI のコンテナ制御オブジェクトは主にオブジェクト インスタンスの作成を制御します。反転は正の方向と相対的なものですが、何が正の方向とみなされるのでしょうか?通常の状況でアプリケーションを考えてみましょう。A の中で C を使用したい場合はどうしますか?もちろん、C のオブジェクトは直接作成されます。つまり、必要な外部リソース C がクラス A で能動的に取得されます。この状況を順方向と呼びます。では、逆とは何でしょうか?つまり、クラス A は積極的に C を取得するのではなく、IoC/DI コンテナが C のインスタンスを取得するのを受動的に待ち、それを逆にクラス A に注入します。
5. 依存関係の注入と制御の反転は同じ概念ですか?
答え: 上記からわかるように、依存関係の注入はアプリケーションの観点から説明されています。制御はコンテナからのもの 説明の観点から完全に説明すると、コンテナはアプリケーションを制御し、コンテナはアプリケーションに必要な外部リソースをアプリケーションに逆に注入します。
例を通して依存性注入の実装方法を見てみましょう:
1. コンストラクター注入
<?phpclass Book { private $db_conn; public function __construct($db_conn) { $this->db_conn = $db_conn; }}
2. セッター注入
<?php<br /> <br />class book{<br /> private $db;<br /> private $file;<br /> function setdb($db){<br /> $this->db=$db;<br /> }<br /> function setfile($file){<br /> $this->file=$file;<br /> }<br />}<br />class file{}<br />class db{}<br />...<br /><br />class test{<br /> $book = new Book(); $book->setdb(new db()); <br /> $book->setfile(new file());<br />}?>
上記 2 つ このメソッドのコードは非常に複雑ですしかし、多くの依存関係を注入する必要がある場合、多くの行を追加することになり、管理がより困難になります。
より良い解決策は、すべての依存関係のコンテナとしてクラスを作成することです。このクラスでは、必要な依存関係を保存、作成、取得、検索できます
<?phpclass Ioc { protected $db_conn; public static function make_book() { $new_book = new Book(); $new_book->set_db(self::$db_conn); //... //... //其他的依赖注入 return $new_book; }}
この時点で、本を取得したい場合は、インスタンスは $newone = Ioc::makebook(); を実行するだけです
上記はコンテナの具体的な例です
<?phpclass Ioc {/*** @var 注册的依赖数组*/ protected static $registry = array(); /** * 添加一个resolve到registry数组中 * @param string $name 依赖标识 * @param object $resolve 一个匿名函数用来创建实例 * @return void */ public static function register($name, Closure $resolve) { static::$registry[$name] = $resolve; } /** * 返回一个实例 * @param string $name 依赖的标识 * @return mixed */ public static function resolve($name) { if ( static::registered($name) ) { $name = static::$registry[$name]; return $name(); } throw new Exception('Nothing registered with that name, fool.'); } /** * 查询某个依赖实例是否存在 * @param string $name id * @return bool */ public static function registered($name) { return array_key_exists($name, static::$registry); }}を使用して、特定の依存関係注入メソッドを記述しない方が良いです。
これで、次の方法で
<?php$book = Ioc::registry('book', function(){$book = new Book;$book->setdb('...');$book->setprice('...');return $book;}); //注入依赖$book = Ioc::resolve('book');?>を登録して注入できます。