控制反轉(zhuǎn)(IOC)模式(又稱DI:Dependency Injection)就是Inversion of Control,控制反轉(zhuǎn)。在Java開(kāi)發(fā)中,IoC意味著將你設(shè)計(jì)好的類交給系統(tǒng)去控制,而不是在你的類內(nèi)部控制。這稱為控制反轉(zhuǎn)。
IoC(Inversion of Control)是近年來(lái)興起的一種思想,不僅僅是編程思想。主要是協(xié)調(diào)各組件間相互的依賴關(guān)系,同時(shí)大大提高了組件的可移植性,組件的重用機(jī)會(huì)也變得更多。在傳統(tǒng)的實(shí)現(xiàn)中,由程序內(nèi)部代碼來(lái)控制程序之間的關(guān)系。我們經(jīng)常使用new關(guān)鍵字來(lái)實(shí)現(xiàn)兩組鍵間關(guān)系的組合,這種實(shí)現(xiàn)的方式會(huì)造成組件之間耦合(一個(gè)好的設(shè)計(jì),不但要實(shí)現(xiàn)代碼重用,還要將組件間關(guān)系解耦)。IoC很好的解決了該問(wèn)題,它將實(shí)現(xiàn)組件間關(guān)系從程序內(nèi)部提到外部容器來(lái)管理。也就是說(shuō)由容器在運(yùn)行期將組件間的某種依賴關(guān)系動(dòng)態(tài)的注入組件中。控制程序間關(guān)系的實(shí)現(xiàn)交給了外部的容器來(lái)完成。即常說(shuō)的好萊塢原則“Don't call us, we'll call you”。
分離關(guān)注( Separation of Concerns : SOC)是Ioc模式和AOP產(chǎn)生最原始動(dòng)力,通過(guò)功能分解可得到關(guān)注點(diǎn),這些關(guān)注可以是 組件Components, 方面Aspects或服務(wù)Services。
從GOF設(shè)計(jì)模式中,我們已經(jīng)習(xí)慣一種思維編程方式:Interface Driven Design 接口驅(qū)動(dòng),接口驅(qū)動(dòng)有很多好處,可以提供不同靈活的子類實(shí)現(xiàn),增加代碼穩(wěn)定和健壯性等等,但是接口一定是需要實(shí)現(xiàn)的,也就是如下語(yǔ)句遲早要執(zhí)行:
AInterface a = new AInterfaceImp();
AInterfaceImp是接口AInterface的一個(gè)子類,Ioc模式可以延緩接口的實(shí)現(xiàn),根據(jù)需要實(shí)現(xiàn),有個(gè)比喻:接口如同空的模型套,在必要時(shí),需要向模型套注射石膏,這樣才能成為一個(gè)模型實(shí)體,因此,我們將人為控制接口的實(shí)現(xiàn)成為“注射”。
Ioc英文為 Inversion of Control,即反轉(zhuǎn)模式,這里有著名的好萊塢理論:你呆著別動(dòng),到時(shí)我會(huì)找你。
其實(shí)Ioc模式也是解決調(diào)用者和被調(diào)用者之間的一種關(guān)系,上述AInterface實(shí)現(xiàn)語(yǔ)句表明當(dāng)前是在調(diào)用被調(diào)用者AInterfaceImp,由于被調(diào)用者名稱寫(xiě)入了調(diào)用者的代碼中,這產(chǎn)生了一個(gè)接口實(shí)現(xiàn)的原罪:彼此聯(lián)系,調(diào)用者和被調(diào)用者有緊密聯(lián)系,在UML中是用依賴 Dependency 表示。
但是這種依賴在分離關(guān)注的思維下是不可忍耐的,必須切割,實(shí)現(xiàn)調(diào)用者和被調(diào)用者解耦,新的Ioc模式 Dependency Injection 模式由此產(chǎn)生了, Dependency Injection模式是依賴注射的意思,也就是將依賴先剝離,然后在適當(dāng)時(shí)候再注射進(jìn)入。
一、Ioc模式(Dependency Injection模式)有三種:
第一種類型 從JNDI或ServiceManager等獲得被調(diào)用者,這里類似ServiceLocator模式。 1.EJB/j2ee 2. Avalon(Apache的一個(gè)復(fù)雜使用不多的項(xiàng)目)
第二種類型 使用JavaBeans的setter方法 1. Spring Framework,2.WebWork/XWork
第三種類型 在構(gòu)造方法中實(shí)現(xiàn)依賴 1. PicoContainer,2. HiveMind
有過(guò)EJB開(kāi)發(fā)經(jīng)驗(yàn)的人都知道,每個(gè)EJB的調(diào)用都需要通過(guò)JNDI尋找到工廠性質(zhì)的Home接口,在我的教程EJB是什么章節(jié)中,我也是從依賴和工廠模式角度來(lái)闡述EJB的使用。
在通常傳統(tǒng)情況下,為了實(shí)現(xiàn)調(diào)用者和被調(diào)用者解耦,分離,一般是通過(guò)工廠模式實(shí)現(xiàn)的,下面將通過(guò)比較工廠模式和Ioc模式不同,加深理解Ioc模式。
二、工廠模式和Ioc
假設(shè)有兩個(gè)類B 和 C:B作為調(diào)用者,C是被調(diào)用者,在B代碼中存在對(duì)C的調(diào)用:
java 代碼