IOC--1 - stonezhuzisgu的專欄 - CSDNBlog(轉載)

IoC是什麼?Inversion of Control,即反轉控制,或許說爲依賴注入更爲合適。IoC就是IoC,不是什麼技術,與GoF一樣,是一種設計模式。

    Interface Driven Design接口驅動,接口驅動有很多好處,可以提供不同靈活的子類實現,增加代碼穩定和健壯性等等,但是接口一定是需要實現的,也就是如下語句遲早要執行:AInterface a = new AInterfaceImp(); 這樣一來,耦合關係就產生了,如:
    Class A{
       AInterface a;
       A(){}
       aMethod(){
          a = new AInterfaceImp();
       }
    }
ClassA與AInterfaceImp就是依賴關係,如果想使用AInterface的另外一個實現就需要更改代碼了。當然我們可以建立一個Factory來根據條件生成想要的AInterface的具體實現,即:
    InterfaceImplFactory{
        AInterface create(Object condition){
            if(condition = condA){
                return new AInterfaceImpA();
            }elseif(condition = condB){
                return new AInterfaceImpB();
            }else{
                return new AInterfaceImp();
            }
        }
    }
表面上是在一定程度上緩解了以上問題,但實質上這種代碼耦合並沒有改變。通過IoC模式可以徹底解決這種耦合,它把耦合從代碼中移出去,放到統一的XML文件中,通過一個容器在需要的時候把這個依賴關係形成,即把需要的接口實現注入到需要它的類中,這可能就是“依賴注入”說法的來源了。
    IOC模式,系統中通過引入實現了IOC模式的IOC容器,即可由IOC容器來管理對象的生命週期、依賴關係等,從而使得應用程序的配置和依賴性規範與實際的應用程序代碼分開。其中一個特點就是通過文本的配件文件進行應用程序組件間相互關係的配置,而不用重新修改並編譯具體的代碼。
    當前比較知名的IOC容器有:Pico Container、Avalon 、Spring、JBoss、HiveMind、EJB等。
    在上面的幾個IOC容器中,輕量級的有Pico Container、Avalon、Spring、HiveMind等,超重量級的有EJB,而半輕半重的有容器有JBoss,Jdon等。
    可以把IoC模式看做是工廠模式的昇華,可以把IoC看作是一個大工廠,只不過這個大工廠裏要生成的對象都是在XML文件中給出定義的,然後利用Java 的“反射”編程,根據XML中給出的類名生成相應的對象。從實現來看,IoC是把以前在工廠方法裏寫死的對象生成代碼,改變爲由XML文件來定義,也就是把工廠和對象生成這兩者獨立分隔開來,目的就是提高靈活性和可維護性。
    IoC中最基本的Java技術就是“反射”編程。反射又是一個生澀的名詞,通俗的說反射就是根據給出的類名(字符串)來生成對象。這種編程方式可以讓對象在生成時才決定要生成哪一種對象。反射的應用是很廣泛的,象Hibernate、String中都是用“反射”做爲最基本的技術手段。
    在過去,反射編程方式相對於正常的對象生成方式要慢10幾倍,這也許也是當時爲什麼反射技術沒有普通應用開來的原因。但經SUN改良優化後,反射方式生成對象和通常對象生成方式,速度已經相差不大了(但依然有一倍以上的差距)。
    IoC最大的好處是什麼?因爲把對象生成放在了XML裏定義,所以當我們需要換一個實現子類將會變成很簡單(一般這樣的對象都是現實於某種接口的),只要修改XML就可以了,這樣我們甚至可以實現對象的熱插撥(有點象USB接口和SCIS硬盤了)。
    IoC最大的缺點是什麼?(1)生成一個對象的步驟變複雜了(其實上操作上還是挺簡單的),對於不習慣這種方式的人,會覺得有些彆扭和不直觀。(2)對象生成因爲是使用反射編程,在效率上有些損耗。但相對於IoC提高的維護性和靈活性來說,這點損耗是微不足道的,除非某對象的生成對效率要求特別高。(3)缺少IDE重構操作的支持,如果在Eclipse要對類改名,那麼你還需要去XML文件裏手工去改了,這似乎是所有XML方式的缺憾所在。
IOC實現初探
   IOC關注服務(或應用程序部件)是如何定義的以及他們應該如何定位他們依賴的其它服務。通常,通過一個容器或定位框架來獲得定義和定位的分離,容器或定位框架負責:
  • 保存可用服務的集合
  • 提供一種方式將各種部件與它們依賴的服務綁定在一起
  • 爲應用程序代碼提供一種方式來請求已配置的對象(例如,一個所有依賴都滿足的對象), 這種方式可以確保該對象需要的所有相關的服務都可用。
  現有的框架實際上使用以下三種基本技術的框架執行服務和部件間的綁定:
  • 類型1 (基於接口): 可服務的對象需要實現一個專門的接口,該接口提供了一個對象,可以從用這個對象查找依賴(其它服務)。早期的容器Excalibur使用這種模式。
  • 類型2 (基於setter): 通過JavaBean的屬性(setter方法)爲可服務對象指定服務。HiveMind和Spring採用這種方式。
  • 類型3 (基於構造函數): 通過構造函數的參數爲可服務對象指定服務。PicoContainer只使用這種方式。HiveMind和Spring也使用這種方式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章