最近 ThinkPHP5 フレームワークを使用しているのですが、そのソース コードを調べたところ、依存性注入 (制御の反転) が多くの場所で使用されていることがわかりました。依存性注入とは何かについて簡単に説明する必要があると感じました。それの使い方。
まず例を見てみましょう:
<?php class A { public $b; public $c; public function A() { //TODO } public function Method() { $this->b=new B(); $this->c=new C(); $this->b->Method(); $this->c->Method(); //TODO } } class B { public function B() { //TODO } public function Method() { //TODO echo 'b'; } } class C { public function C() { //TODO } public function Method() { //TODO echo 'c'; } } $a=new A(); $a->Method(); ?>
上記のコードは、次の 1 つの文を簡単に理解できます:
クラス A はクラス B とクラス C に依存します
つまり、将来の開発プロセスの場合、クラス B は、クラス C を変更するか、変更する必要があります。関数の名前変更、関数パラメータの数の変更、さらにはクラス構造全体の調整が必要になったら、クラス A にも対応する調整を行う必要があります。クラス A の独立性は失われます。便利なことに、これは「1 つのことが全体を引き起こす」と呼ばれるもので、2 つのカテゴリを 2 人が別々に作成すると、この時点で競合が発生することがよくあります。 。 。
カテゴリBとCを本当に変更する必要がある場合、カテゴリAのコードを変更しない、またはできるだけ変更しない方法はありますか?ここでは制御の反転が使用されます。
高レベルのモジュールは低レベルのモジュールに依存すべきではなく、両方とも抽象化に依存する必要があります。
Inversion of Control (IOC) はアイデアであり、Dependency Injection (DI) はこのアイデアを実装するための手法です。
最初のメソッドは、コンストラクターインジェクションと呼ばれます (このメソッドは推奨されませんが、使用しないよりは良いです)
class A { public $b; public $c; public function A($b,$c) { $this->b=$b; $this->c=$c; } public function Method() { $this->b->Method(); $this->c->Method(); } }
クライアントクラスは次のように記述されます:
$a=new A(new B(),new C()); $a->Method();
Constructor ofクラス A コンストラクターのパラメーターを通じて渡されたクラス B と C に依存して、少なくとも 1 つのことが達成されます。つまり、クラス B オブジェクト b とクラス C オブジェクト c の作成がクラス A の外に移動されるため、クラス Bと C が変更されます。クラス A は変更する必要はありません。クライアント クラスで変更するだけです
ある日、クラス B を拡張して、クラス B の 2 つのサブクラスを作成する必要がある場合
class B { public function B() { //TODO } public function Method() { //TODO echo 'b'; } } class B1 extends B { public function B1() { //TODO } public function Method() { echo 'b1'; } } class B2 extends B { public function B2() { //TODO } public function Method() { echo 'b2'; } }
また、非常に単純です。クライアント クラスは次のようになります。
$a=new A(new B2(),new C()); $a->Method();
したがって、クラス A は、クライアント クラスに関する限り、クラス B がどのサブクラスを持っているかを気にする必要はありません。
2 番目のメソッドが呼び出されます: ファクトリ パターン インジェクション (推奨)
class Factory { public function Factory() { //TODO } public function create($s) { switch($s) { case 'B': { return new B(); break; } case 'C': { return new C(); break; } default: { return null; break; } } } }
クラス A のコードは次のように変更されます:
class A { public $b; public $c; public function A() { //TODO } public function Method() { $f=new Factory(); $this->b=$f->create('B'); $this->c=$f->create('C'); $this->b->Method(); $this->c->Method(); //TODO } }
実際、少なくともクラスの場合、小さな部分が分離されています。 B および関数パラメータの変更など、クラス C のコンストラクターが変更された場合は、Factory クラスを変更するだけで済みます。
抽象化は詳細に依存すべきではなく、詳細は抽象化に依存する必要があります。
クラスBとクラスCのメソッドを抽象化してインターフェースを作る
interface IMethod { public function Method(); }
このように、クラスAの$b変数と$c変数は特定の変数ではなくなりますが、抽象型変数の場合、メソッドがどのように実装されるかは、実行される瞬間までわかりません。
class B implements IMethod { public function B() { //TODO } public function Method() { //TODO echo 'b'; } } class C implements IMethod { public function C() { //TODO } public function Method() { //TODO echo 'c'; } }
いくつかのポイントを要約すると:
1. クラス A のクラス B オブジェクトとクラス C オブジェクトの作成をクラス A の外に移動します
2。これで、A が Factory に依存し、Factory が B と C に依存するようになります。
PHP の制御反転 (IOC) と依存関係の挿入 (DI) のサンプル コードの詳細な説明
PHP の依存関係の挿入 (DI) と制御の反転 (IoC) のサンプル チュートリアルを共有する
PHP 依存性注入 (DI) と制御反転 (IoC) のサンプルチュートリアル
以上がPHPでのIocとDiの例の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。