標籤:指定 獨立 依賴 實體 depend 方式 解決 影響 開發
控制反轉(Inversion of Control,縮寫為IoC),是物件導向編程的一種設計原則,可以用來減低電腦代碼之間的耦合度。其中最常見的方式叫做 依賴注入(Dependency Injection,簡稱DI). 還有一種方式叫做 "依賴尋找" (Dependency Lookup). 通過控制反轉,對象
在被建立時,由一個調控系統內所有對象的外界實體,將其所依賴的對象的引用傳遞給它。也可以說,依賴被注入到對象中.
Class A中用到了Class B的對象b,一般情況下,需要在A的代碼中顯式的new一個B的對象。
採用依賴注入技術之後,A的代碼只需要定義一個私人的B對象,不需要直接new來獲得這個對象,而是通過相關的容器控製程序來將B對象在外部new出來並注入到A類裡的引用中。而具體擷取的方法、對象被擷取時的狀態由設定檔(如XML)來指定。
依賴注入有如下實現方式:
基於介面。實現特定介面以供外部容器注入所依賴類型的對象。
基於 set 方法。實現特定屬性的public set方法,來讓外部容器調用傳入所依賴類型的對象。
基於建構函式。實現特定參數的建構函式,在建立對象時傳入所依賴類型的對象。
1. 依賴
如果在 Class A 中,有 Class B 的執行個體,則稱 Class A 對 Class B 有一個依賴。例如下面類 Human 中用到一個 Father 對象,我們就說類 Human 對類 Father 有一個依賴。
public class Human {
...
Father father;
...
public Human() {
father = new Father();
}
}
仔細看這段代碼我們會發現存在一些問題:
(1). 如果現在要改變 father 產生方式,如需要用 new Father(String name) 初始化 father,需要修改 Human 代碼;
(2). 如果想測試不同 Father 對象對 Human 的影響很困難,因為 father 的初始化被寫死在了 Human 的建構函式中;
(3). 如果 new Father() 過程非常緩慢,單測時我們希望用已經初始化好的 father 對象 Mock 掉這個過程也很困難。
2. 依賴注入
上面將依賴在建構函式中直接初始化是一種 Hard init 方式,弊端在於兩個類不夠獨立,不方便測試。我們還有另外一種 Init 方式,如下:
public class Human {
...
Father father;
...
public Human(Father father) {
this.father = father;
}
}
上面代碼中,我們將 father 對象作為建構函式的一個參數傳入。在調用 Human 的構造方法之前外部就已經初始化好了 Father 對象。像這種非自己主動初始化依賴,而通過外部來傳入依賴的方式,我們就稱為依賴注入。
現在我們發現上面 1 中存在的兩個問題都很好解決了,簡單的說依賴注入主要有兩個好處:
(1). 解耦,將依賴之間解耦。
(2). 因為已經解耦,所以方便做單元測試,尤其是 Mock 測試。
軟體開發--依賴注入