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