まず例を見てみましょう:
<?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 の独立性が失われます。これは、いわゆる「一つのことが全体に影響を与える」という開発プロセスにおいて非常に不便です。このとき、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();
クラスのコンストラクターA は B に依存します。クラスとクラス C は、コンストラクターのパラメーターを通じて渡されます。つまり、クラス 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 は、クライアント クラスに関心がある限り、クラス B がどのサブクラスを持つかを気にする必要はありません。
ファクトリ パターン
インジェクション (推奨)$a=new A(new B2(),new C()); $a->Method();クラス A のコードは次のように変更されます:
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; } } } }
実際、少なくともクラスの場合は、小さな部分が分離されています。 B および 関数パラメーターの変更など、クラス C の
コンストラクター
抽象化は詳細に依存すべきではなく、詳細は抽象化に依存する必要があります。
クラス B と C のメソッドを抽象化し、インターフェース
を作成します。このようにして、クラス A の $bclass 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 } }
variable と $c 変数は特定の変数ではなくなります。 抽象クラス
型変数。メソッドが実行されるまでどのように実装されるかわかりません。概要 いくつかのポイント:1. クラス A 内のクラス B オブジェクトとクラス C オブジェクトの作成をクラス A の外に移動します
2 元々クラス A はクラス B とクラス C に依存していました。 . ここで、A は Factory に依存し、Factory は B と C に依存します。
以上がPHP の制御反転と依存関係の注入の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。