2014-02-27 142 views
4

我知道一些OOP和已經閱讀這個那個,但我不是一個鐵桿OOP的傢伙,有沒有正規的訓練,不能背出爲什麼有些東西應該使用依賴注入或沒有,可能無法識別設計中的所有依賴關係,因此我的問題。OOP依賴關係:依賴注入與註冊

在這裏回答問題SO(Using a object in methods of other objects),我開始懷疑自己。至於依賴關係,其中一個更好還是更糟,或者兩者都可以接受?任何設計限制?

我已閱讀並理解這兩種,但還未曾遇到過的比較。爲什麼會一個是在設計中更好地使用等

依賴注入:

class myClass { 
    private $db; 

    public function __construct($db) { 
     $this->db = $db; 
    } 
} 

註冊(也許還有其他方面):

class myClass { 
    private $db; 

    public function __construct() { 
     $this->db = Registry::get('db'); 
    } 
} 
+0

兩者都不是更好或更壞。就我個人而言,我更喜歡第一個,因爲IMO儘可能隱藏您的輸入參數,最終使得調試變得更加困難。 – Tularis

+0

是的:)但我沒有意識到鏈接指向德國文章..對不起:)讓我們檢查一下,如果我可以找到其他的東西... – hek2mgl

+0

@ hek2mgl:這是有道理的(當我將它翻譯爲我的Deutsch ist klein) – AbraCadaver

回答

5

這兩種方法都可以實現的依賴注入。基本上,依賴注入意味着定義一種方法來配置(注入)要在運行時使用的類,以便使代碼更靈活,而不是在代碼中使用硬編碼的類名和構造函數。依賴注入遵循一個稱爲inversion of control的原則。

這對於測試代碼尤其是有趣的,但可以在不同的地方要提出申請,靈活和易於維護等情況下使用。

雖然依賴注入大多作爲DI container稱爲,它通常可使用幾個不同的方法來完成 - 其也可以共存。使用利用設定器依賴注入容器

  • 通類依賴性,使用中央註冊表構造方法或方法ARGS
  • (只要它是可配置的)
    • :這裏談到的(不完全的)列表方法
    • 使用配置文件來設置依賴
    • 用戶輸入
    • ...
  • +0

    這是一個完美的答案。 – abnvp

    +0

    依賴依賴注入器容器的註冊表類如何?這可能是兩全其美嗎? –

    6

    它與可測性有很大關係。

    在你的例子中,第一個(依賴注入)更好。它的更好的原因是因爲它接受db作爲參數,這意味着這是可檢驗的,可以使用一個模擬db用於測試和測試myClass做正確的事吧。

    第二個例子(註冊)不推薦,因爲不僅myClass取決於db,現在也要看Registry,而最糟糕的是,它知道如何獲得db。它太聰明瞭,它應該像第一個一樣愚蠢,愚蠢的東西更容易測試,聰明的東西不是。

    +0

    在第二種情況下,也應該能夠模擬註冊表並將其用於測試。我相信它與個人偏好和開發人員正在使用的DI框架有關 – abnvp

    3

    需要依賴注入,因爲對象需要某些數據才能正確執行其功能。

    依賴注入可以用三種不同的方式進行:

    • 如果對象A依賴對象B上,那麼你就可以創建對象的同時創建對象B
    • 你可以使用一些外部類(如註冊表,配置文件等)來加載依賴項對象,這將使對象的創建與創建依賴關係分離。這稱爲定位器模式,其中您的對象創建依賴於定位器來加載對象。
    • 您可以在別處創建依賴項並將其直接提供給依賴對象。這就是所謂的 '手動進樣'

    每當你做這些,你已經做的依賴注入:

    構造方法注入

    public class ClassA 
    { 
    // declares the dependency in the constructor 
    
    public function ClassA(dependency1:String) 
    {} 
    } 
    
    // and the dependency is created while instantiating the object 
    var objA:ClassA = new ClassA("Hello World"); 
    

    公共屬性注入

    public class ClassA 
    { 
    // declares the dependency as a public property 
    public var helloStr:String; 
    } 
    
    var obj1:ClassA = new ClassA(); 
    
    // dependency is fulfilled by setting a public property after instantiation: 
    obj1.helloStr = "The Zen Master";