關於控制反轉和依賴注入的文章和書籍很多,對其定義也解釋的也仁者見仁,這裏就不贅述了,這是本人(只代表個人觀點)理解之後用通俗的例子和平淡的話詞爲您解釋,希望對您有所幫助:
控制反轉(IoC/Inverse Of Control): 調用者不再創建被調用者的實例,由spring框架實現(容器創建)所以稱爲控制反轉。
依賴注入(DI/Dependence injection) : 容器創建好實例後再注入調用者稱爲依賴注入。
當 某個角色(可能是一個Java實例,調用者)需要另一個角色(另一個Java實例,被調用者)的協助時,在傳統的程序設計過程中,通常由調用者來創建被調 用者的實例,。如果創建被調用者實例的工作不再由調用者來完成,而是由外部容器完成,因此稱爲控制反轉; 創建被調用者 實例的工作通常由外部容器來完 成,然後注入調用者,因此也稱爲依賴注入。
下面一個小實例:
定義一個接口
public interface Person {
void sayHello();
}
第一個實現類:
public class Chinese implements Person {
public void sayHello() {
System.out.println("您好 !");
}
}
第二個實現類:
public class American implements Person {
public void sayHello() {
System.out.println("How do you do .");
}
}
注意這個類與傳統設計有什麼區別:該類調用Person子類的方法,傳統設計在本類中創造實例,而在此類裏並沒有創造實例
public class User {
Person p;
public Person getP() {
return p;
}
//使用setter注入
public void setP(Person p) {
this.p = p;
}
//調用person子類重寫的sayHello方法,這裏的p並沒有實例化
public void function(){
p.sayHello();
}
}
外部‘容器’
public class Container{
public static User getBean(){
Person p=new Chinese();
User user = new User();
//由容器‘注入’實例
user.setP(p);
return user;
}
}
測試類:
public class Test{
public static void main(String[] args){
User user = Container.getBean();
user.function();
}
}
//後臺輸出‘您好’
通過這個例子應該看懂了控制反轉,和依賴注入了吧,這個是不是與傳統設計相‘反了’。:-D
相關知識
依賴和耦合(Dependency and Coupling)
如果模塊A調用模塊B提供的方法,或訪問模塊B中的某些數據成員(當然,在面向對象開發中一般不提倡這樣做),我們就認爲模塊A依賴於模塊B,模塊A和模塊B之間發生了耦合。
那麼,依賴對於我們來說究竟是好事還是壞事呢?
由於人類的理解力有限,大多數人難以理解和把握過於複雜的系統。把軟件系統劃分成多個模塊,可以有效控制模塊的複雜度,使每個模塊都易於理解和維護。但 在這種情況下,模塊之間就必須以某種方式交換信息,也就是必然要發生某種耦合關係。如果某個模塊和其它模塊沒有任何關聯(哪怕只是潛在的或隱含的依賴關 系),我們就幾乎可以斷定,該模塊不屬於此軟件系統,應該從系統中剔除。如果所有模塊之間都沒有任何耦合關係,其結果必然是:整個軟件不過是多個互不相干 的系統的簡單堆積,對每個系統而言,所有功能還是要在一個模塊中實現,這等於沒有做任何模塊的分解。
因此,模塊之間必定會有這樣或那樣的依賴關係,永遠不要幻想消除所有依賴。但是,過強的耦合關係(如一個模塊的變化會造成一個或多個其他模塊也同時發生 變化的依賴關係)會對軟件系統的質量造成很大的危害。特別是當需求發生變化時,代碼的維護成本將非常高。所以,我們必須想盡辦法來控制和消解不必要的耦 合,特別是那種會導致其它模塊發生不可控變化的依賴關係。依賴倒置、控制反轉、依賴注入等原則就是人們在和依賴關係進行艱苦卓絕的鬥爭過程中不斷產生和發 展起來的。
轉自:http://blog.163.com/taodengwen@126/blog/static/87199341201191383429693/