什么是Ioc(Inversion of Control) (zhuan)
這篇短文基本上是改編自Martin Fowler的Inversion of Control Containers and the Dependency Injection pattern,目的呢,是讓讀者能夠在最短時間內(nèi)了解IoC的概念。這也是我一貫的“風(fēng)格”:最短的文字、最精要的內(nèi)容、最清晰的說明。希望我能做到,自勉^_^
在J2EE應(yīng)用開發(fā)中,經(jīng)常遇到的問題就是:如何將不同的組件組裝成為一個內(nèi)聚的應(yīng)用程序?IoC模式可以解決這個問題,其目標(biāo)是將組件的配置與使用分離開。
IoC,Inversion of Control,控制反轉(zhuǎn)[1],其原理是基于OO設(shè)計原則的The Hollywood Principle:Don't call us, we'll call you。也就是說,所有的組件[2]都是被動的(Passive),所有的組件初始化和調(diào)用都由容器負(fù)責(zé)。組件處在一個容器當(dāng)中,由容器負(fù)責(zé)管理。
要說明IoC模式最好的方法是使用代碼。下邊是一段正常的代碼。
class ClassA...
public String aMethod(String arg){
String result = instanceOfClassB.bMethod();
do something;
return result;
}
在上邊的代碼里,我們要解決的問題是:ClassA如何獲得ClassB的實例?一個最直接的方法是在aMethod里聲明:
IClassB instanceOfClassB = new ClassB();
這里使用了一個接口IClassB。
問題是,如果出現(xiàn)這樣的情況:繼續(xù)使用ClassA,但要求用IClassB的另一個實現(xiàn)ClassB2代替ClassB呢?更概括一點說:ClassA怎樣才能找到IClassB的具體實現(xiàn)?很明顯,上述代碼增加ClassA和ClassB的耦合度,以致于無法在不修改ClassA的情況下變更IClassB的具體實現(xiàn)。
IoC模式就是用于解決這樣的問題。當(dāng)然,還有其他的方法,比如Service Locator模式,但現(xiàn)在我們只關(guān)注IoC。如前所述,IoC容器負(fù)責(zé)初始化組件(如IClassB),并將實例交給使用者。使用代碼或配置文件以聲明的方式將接口與實例關(guān)聯(lián)起來,IoC容器負(fù)責(zé)進(jìn)行實際的調(diào)用處理。對于調(diào)用者,只需要關(guān)注接口就行了。
根據(jù)實例傳入方式的不同,IoC分為type 1 IoC(接口注入[3])、type 2 IoC(設(shè)值方法注入)和type 3 IoC(構(gòu)造子注入)。分別用代碼說明如下:
type 1 IoC(接口注入)
public interface GetClassB {
void getClassB(IClassB instanceOfClassB);
}
class ClassA implements GetClassB…
IClassB instanceOfClassB;
void getClassB(IClassB instanceOfClassB) {
this.instanceOfClassB = instanceOfClassB;
}
type 2 IoC(設(shè)值方法注入)
class ClassA...
IClassB instanceOfClassB;
public void setFinder(IClassB instanceOfClassB) {
this.instanceOfClassB = instanceOfClassB;
}
type 3 IoC(構(gòu)造子注入)
class ClassA…
ClassB instanceOfClassB;
public classA(IClassB instanceOfClassB) {
this. instanceOfClassB = instanceOfClassB;
}
Spring使用的是type 2 IoC。[1] 在Martin Fowler的Inversion of Control Containers and the Dependency Injection pattern一文中,作者提出本模式更準(zhǔn)確的名稱應(yīng)該是Dependency Injection。考慮到使用上的習(xí)慣,在本文檔中我們將繼續(xù)使用IoC的概念。
[2] 同一篇文章中,Martin Fowler還提出了Componet(組件)與Service(服務(wù))的區(qū)別問題。我個人認(rèn)為“組件”更有助于幫助我們理解IoC的概念,所以在本文檔中使用“組件”來代表“組件或服務(wù)”
[3] 如上所述,注入是另一種說法,此處只用于輔助說明。
posted on 2006-03-11 08:28 都市淘沙者 閱讀(2955) 評論(0) 編輯 收藏 所屬分類: Spring+Struts+Hibernate