什麼是控制反轉?
軟件中的對象就像齒輪一樣,協同工作、互相耦合。若有一個零件不能工作,便會導致整個系統的崩潰。這種系統稱爲強耦合系統。
齒輪組中齒輪之間的齧合關係與軟件系統對象的耦合關係十分相似,對象的耦合是必要的,也是無法避免的,這是協同工作的基礎。
隨着對象之間的依賴關係越來越複雜,對象之間的多重依賴性關係也隨之經常出現。這就對架構師和系統設計師關於系統的分析的設計提出了巨大的挑戰。
對象之間耦合度過高的系統,必然會出現牽一髮而動全身的情形。
爲了解決對象間耦合度過高的問題,Michael Mattson提出了IoC理論
,用來實現對象之間的“解耦”。
控制反轉(Inversion of Control)是一種面向對象編程中的一種設計原則,用來降低代碼間的耦合度。其基本思想是:藉助於“第三方”實現具有依賴關係的對象間的解耦。
由於引入了第三方loC容器,A、B、C、D四個對象沒有了耦合關係,齒輪之間的傳動全部依賴於第三方,這樣就把loC容器變成了系統的核心,它就像“粘合劑”一樣,將A、B、C、D四個對象粘合起來發揮作用。
“控制反轉”實際上是變主動爲被動的過程
在沒有引入loC容器前,對象A在初始化或者運行過程中,必須自己主動去創建或者使用已經創建的對象B,無論創建還是使用,主動權都在A手上。
在引入loC容器後,對象A與B失去了直接聯繫,當對象A需要對象B時,loC容器會主動創建一個對象B注入到對象A需要的地方,對象A只需要被動接受就可以了。
什麼是依賴注入?
依賴注入(Dependency Injection) 常常簡稱爲:DI。它是實現控制反轉(Inversion of Control – IoC)的一個模式。
它的本質目的是解耦,保持軟件組件之間的鬆散耦合,爲設計開發帶來靈活性。
什麼是依賴?
如果在 Class A 中,有 Class B 的實例,則稱 Class A 對 Class B 有一個依賴。例如下面類 Human
中用到一個 Father
對象,我們就說類 Human
對類 Father
有一個依賴。
public class Human {
...
Father father;
...
public Human() {
father = new Father();
}
}
如果現在要改變 father
生成方式,如需要用new Father(String name)
初始化 father
,需要修改 Human
代碼,因爲 father
的初始化被寫死在了 Human
的構造函數中,影響效率。
依賴注入
public class Human {
...
Father father;
...
public Human(Father father) {
this.father = father;
}
}
上面代碼中,我們將 father
對象作爲構造函數的一個參數傳入。在調用 Human
的構造方法之前外部就已經初始化好了 Father
對象。像這種非自己主動初始化依賴,而通過外部來傳入依賴的方式,我們就稱爲依賴注入。
控制反轉和依賴注入的關係
我們已經分別解釋了控制反轉和依賴注入的概念。有些人會把控制反轉和依賴注入等同,但實際上它們有着本質上的不同。
控制反轉是一種思想
依賴注入是一種設計模式