2011-12-09 27 views
2

我一直在閱讀依賴注入,我想我非常理解概念,包括構造函數注入和setter注入。有關依賴關係的查詢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; 
    } 
} 

何時應該傳遞一個對象的方法和什麼時候應該經由構造/ setter方法使用依賴注入? 有什麼經驗法則或什麼時候使用這兩個選項之一的最佳做法?

感謝您的幫助提前。

+0

如果你的例子更具體一些,那麼解決你的問題會更容易。什麼是'anotherClass',aMethod用它做什麼? – middus

+0

好的,一個場景:我在我的電子商務網站上有一個Basket類。這個Basket類中的一個方法叫做listProducts()。這是需要訪問產品數據庫表的唯一方法。這有它自己的數據映射器類叫做productsMapper。 第二個場景:我有一個save()方法的數據映射器類。此方法需要該行的模型。將這種模式提供給整個班級是毫無意義的。 – Dan

+0

好的,我非常直觀地發現這一點,所以在這裏有具體的答案。第一種情況:注入 - 籃子可能會提出幾個DB請求。第二種情況:參數,您只需要一次數據來存儲,並可能需要使用同一對象的函數來存儲其他模型。 – middus

回答

2

你提到一個經驗法則,所以這裏是:

問自己一個問題:可能有人合法地調用此方法兩次對同一對象,在兩個調用的參數提供不同的值?

如果是,則將其作爲參數保留。如果不是,那麼它就像你描述的那樣是一個很好的注射候選人。

This是第一種方法的一個很好的例子,其中刪除參數並在類中注入依賴關係反而是一個非常糟糕的主意。 C#而不是PHP,但你得到的圖片。

+0

啊,這確實有很大的意義,謝謝。特別是使用數據映射器。將它作爲參數是否會減少我可以單元測試的難度?順便說一句,我從來沒有試過單元測試任何東西! – Dan

+0

@Azriel:當然不是。硬編碼類型只會降低您的單元測試能力。 – Jon

+0

我喜歡你的榜樣,簡單而重要。通過硬編碼類型,我假設你的意思是在aMethod()方法中有$ anotherClass = new anotherClass()? – Dan

1

一個班級的內部運作是沒有什麼業務,但這個班級本身。如果只有一個函數需要依賴關係,那就這樣吧。

或者你可能想知道爲什麼只有一個函數有依賴關係,你是否可以做兩個單獨的事情嗎?

您不希望在構造函數中注入依賴關係的唯一原因是使得該資源的成本非常高(準備好磁盤上的大文件,連接到遠程主機等),但即使在這種情況下,您可以將「代理」或「延遲」對象作爲「承諾」傳遞給您,如果您需要的話,您可以獲得依賴關係。

+0

但是,有些情況下,例如,將數據庫行模型插入數據庫的Data Mapper。即使在Zend QuickStart指南中,我看到: 公共功能保存(Application_Model_Guestbook $留言本) { } 這是無效的嗎? – Dan

+0

@Azriel當然是,因爲它是一個參數。如果你想保存一些東西,你需要知道要保存什麼。 – middus

+0

@middus這正是我所做的一點!我只是認爲它與這個答案中給出的內容相沖突。 – Dan