2011-12-09 7 views
2

私は依存性注入について読んできましたが、私はコンストラクタ注入とセッタ注入を含む概念をかなり理解していると思います。PHPでの依存性注入に関する問い合わせ

しかし、私は次のシナリオでどうなるのかわからない午前:

は、私は多くのメソッドを持つクラスを持っていると言うが、は一つだけこれらの方法の特定の他のオブジェクトが必要です。このオブジェクトをメソッドに提供するにはどうしたらいいですか?私はちょうど直接そのようなパラメータとしてメソッドにオブジェクトを渡すべきではありません:

class aClass 
{ 
    function aMethod(anotherClass $anotherClass) 
    { 
     anotherClass->hello(); 
    } 

    function otherMethods() 
    { 
    } 
    ..... 
} 

他のオプションは、不要と思われるクラス全体にそれを提供することです。

class aClass 
{ 
    protected $_anotherClass; 

    function aMethod() 
    { 
     anotherClass->hello(); 
    } 

    function otherMethods() 
    { 
    } 
    ..... 

    function setAnotherClass(anotherClass $anotherClass) 
    { 
      $this->_anotherClass; 
    } 
} 

私はメソッドにオブジェクトを渡す必要があるとき、私はコンストラクタ/セッターを経由して依存性注入を使用する必要がある場合:そうのような? これらの2つのオプションのどちらを使用するかについての経験則やベストプラクティスはありますか?事前にあなたの助けのための

感謝。

+0

あなたの例がより具体的であれば、あなたの質問を理解しやすくなります。 'anotherClass'とは何ですか?また、メソッドはそれと何をしますか? – middus

+0

さて、1つのシナリオ:私は電子商取引のウェブサイトにバスケットのクラスを持っています。このバスケットクラスのメソッドの1つはlistProducts()です。これは、製品のデータベーステーブルへのアクセスを必要とする唯一の方法です。これには、productsMapperという独自のデータマッパークラスがあります。 第2のシナリオ:save()メソッドを持つデータマッパークラスがあります。このメソッドは、行のモデルを必要とします。クラス全体にこのモデルを提供することは全く意味がありません。 – Dan

+0

さて、私はこれを非常に直観的に見つけるので、ここでは具体的な答えです。最初のシナリオ:注射 - バスケットは少数のDB要求をするかもしれません。第2のシナリオ:パラメータでは、一度だけデータを保存する必要があり、同じオブジェクトの機能を使用して他のモデルを保存することができます。 – middus

答えて

2

あなたはので、ここでそれは、経験則を述べた:誰かが合法的に2回の呼び出しで引数の異なる値を提供し、同じオブジェクトに二回、このメソッドを呼び出すことができます。

は、質問自問してみてください?

「はい」の場合は、それをパラメータのままにします。いいえ、それはあなたが説明するように注射の良い候補です。

Thisは、最初の型のメソッドの良い例です。パラメータを削除し、クラスへの依存関係を注入するのは本当に悪い考えです。 PHPの代わりにC#を使用していますが、画像が表示されます。

+0

ああ、これはかなり意味がある、ありがとう。特にデータマッパーの使用。それをパラメータとして残しても単体テストが容易になるのですか?私は実際にユニットテストを試みたことはありません。 – Dan

+0

@Azriel:もちろんです。単体テストの能力を低下させる唯一のものは、ハードコーディングタイプです。 – Jon

+0

私はあなたの例を、シンプルでポイントに好きです。タイプをハードコードすることによって、あなたはaMethod()メソッド内で$ anotherClass = new anotherClass()を持つことを意味すると思いますか? – Dan

1

クラスの内部動作は、何もしていないビジネスですが、そのクラス自体です。依存関係を必要とする関数が1つだけの場合は、そのようにしてください。

また、なぜ1つの関数だけが依存関係にあるのか不思議に思うかもしれませんが、おそらくクラスが2つの別々のことをしていますか?

コンストラクタに依存関係を挿入したくない理由は、そのリソースを作成するコストが非常に高い(ディスク上の大きなファイルを準備したり、リモートホストに接続するなど)、その場合でもあなたはそれが必要な場合にあなたが依存関係を得ることができる「約束」として「プロキシ」または「遅延」オブジェクトを渡すことができます。

+0

しかし、例えば、データベース行のモデルをデータベースに挿入するData Mapperのようなシナリオがあります。 Zend QuickStartガイドでも、私はこれを参照してください: public function save(Application_Model_Guestbook $ guestbook) { } これは無効ですか? – Dan

+0

@Azrielそれはパラメータなのでもちろんです。あなたが何かを保存したい場合は、何を保存するかを知る必要があります。 – middus

+0

@middusそれは私が作っていたまさにポイントです!私はちょうどそれがこの答えで与えられたものと矛盾していると思った。 – Dan