<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    wonderer's program

    everything will be better
    posts - 19, comments - 6, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    轉(zhuǎn):什么是IOC

    Posted on 2007-10-28 16:50 wonderer 閱讀(686) 評論(0)  編輯  收藏 所屬分類: java

    什么是IOC呢,在網(wǎng)上搜到了一非常有意思的講解。
    IoC就是Inversion of Control,控制反轉(zhuǎn)。在Java開發(fā)中,IoC意味著將你設(shè)計(jì)好的類交給系統(tǒng)去控制,而不是在你的類內(nèi)部控制。這稱為控制反轉(zhuǎn)。

    下面我們以幾個(gè)例子來說明什么是IoC

    假設(shè)我們要設(shè)計(jì)一個(gè)Girl和一個(gè)Boy類,其中Girl有kiss方法,即Girl想要Kiss一個(gè)Boy。那么,我們的問題是,Girl如何能夠認(rèn)識(shí)這個(gè)Boy?

    在我們中國,常見的MM與GG的認(rèn)識(shí)方式有以下幾種
    1 青梅竹馬; 2 親友介紹; 3 父母包辦
    那么哪一種才是最好呢?

    青梅竹馬:Girl從小就知道自己的Boy。

       1: public class Girl { 
       2:     void kiss(){ 
       3:     Boy boy = new Boy(); 
       4:     } 
       5: }

    然而從開始就創(chuàng)建的Boy缺點(diǎn)就是無法在更換。并且要負(fù)責(zé)Boy的整個(gè)生命周期。如果我們的Girl想要換一個(gè)怎么辦?(嚴(yán)重不支持Girl經(jīng)常更換Boy,#_#)

    親友介紹:由中間人負(fù)責(zé)提供Boy來見面

       1: public class Girl { 
       2:     void kiss(){ 
       3:         Boy boy = BoyFactory.createBoy(); 
       4:     } 
       5: }

    親友介紹,固然是好。如果不滿意,盡管另外換一個(gè)好了。但是,親友BoyFactory經(jīng)常是以Singleton的形式出現(xiàn),不然就是,存在于Globals,無處不在,無處不能。實(shí)在是太繁瑣了一點(diǎn),不夠靈活。我為什么一定要這個(gè)親友摻和進(jìn)來呢?為什么一定要付給她介紹費(fèi)呢?萬一最好的朋友愛上了我的男朋友呢?

    父母包辦:一切交給父母,自己不用費(fèi)吹灰之力,只需要等著Kiss就好了。

       1: public class Girl { 
       2:     void kiss(Boy boy){ 
       3:         // kiss boy 
       4:         boy.kiss(); 
       5:     } 
       6: }

    Well,這是對Girl最好的方法,只要想辦法賄賂了Girl的父母,并把Boy交給他。那么我們就可以輕松的和Girl來Kiss了。看來幾千年傳統(tǒng)的父母之命還真是有用哦。至少Boy和Girl不用自己瞎忙乎了。

    這就是IOC,將對象的創(chuàng)建和獲取提取到外部。由外部容器提供需要的組件。

    我們知道好萊塢原則:“Do not call us, we will call you.” 意思就是,You, girlie, do not call the boy. We will feed you a boy。

    我們還應(yīng)該知道依賴倒轉(zhuǎn)原則即 Dependence Inversion Princinple,DIP

    Eric Gamma說,要面向抽象編程。面向接口編程是面向?qū)ο蟮暮诵摹?

    組件應(yīng)該分為兩部分,即 Service, 所提供功能的聲明 Implementation, Service的實(shí)現(xiàn)

    好處是:多實(shí)現(xiàn)可以任意切換,防止 “everything depends on everything” 問題.即具體依賴于具體。

    所以,我們的Boy應(yīng)該是實(shí)現(xiàn)Kissable接口。這樣一旦Girl不想kiss可惡的Boy的話,還可以kiss可愛的kitten和慈祥的grandmother。
    二、IOC的type

    IoC的Type指的是Girl得到Boy的幾種不同方式。我們逐一來說明。

    IOC type 0:不用IOC

       1: public class Girl implements Servicable { 
       2:     private Kissable kissable; 
       3:     public Girl() { 
       4:         kissable = new Boy(); 
       5:     } 
       6:     public void kissYourKissable() { 
       7:         kissable.kiss(); 
       8:     } 
       9: }

    Girl自己建立自己的Boy,很難更換,很難共享給別人,只能單獨(dú)使用,并負(fù)責(zé)完全的生命周期。

    IOC type 1,先看代碼:代碼

       1: public class Girl implements Servicable { 
       2:  
       3:     Kissable kissable; 
       4:  
       5:     public void service(ServiceManager mgr) { 
       6:         kissable = (Kissable) mgr.lookup(“kissable”); 
       7:     } 
       8:  
       9:     public void kissYourKissable() { 
      10:         kissable.kiss(); 
      11:     } 
      12: }

    這種情況出現(xiàn)于Avalon Framework。一個(gè)組件實(shí)現(xiàn)了Servicable接口,就必須實(shí)現(xiàn)service方法,并傳入一個(gè)ServiceManager。其中會(huì)含有需要的其它組件。只需要在service方法中初始化需要的Boy。

    另外,J2EE中從Context取得對象也屬于type 1。它依賴于配置文件。

    IOC type 2:

       1: public class Girl { 
       2:  
       3:     private Kissable kissable; 
       4:  
       5:     public void setKissable(Kissable kissable) { 
       6:         this.kissable = kissable; 
       7:     } 
       8:  
       9:     public void kissYourKissable() { 
      10:         kissable.kiss(); 
      11:     } 
      12: }

    Type 2出現(xiàn)于Spring Framework,是通過JavaBean的set方法來將需要的Boy傳遞給Girl。它必須依賴于配置文件。

    IOC type 3:

       1: public class Girl { 
       2:  
       3:     private Kissable kissable; 
       4:  
       5:     public Girl(Kissable kissable) { 
       6:         this.kissable = kissable; 
       7:     } 
       8:  
       9:     public void kissYourKissable() { 
      10:         kissable.kiss(); 
      11:     } 
      12: }
      13:  

    這就是PicoContainer的組件 。通過構(gòu)造函數(shù)傳遞Boy給Girl

    PicoContainer container = new DefaultPicoContainer();
    container.registerComponentImplementation(Boy.class);
    container.registerComponentImplementation(Girl.class);
    Girl girl = (Girl) container.getComponentInstance(Girl.class);
    girl.kissYourKissable();

    參考資料

    1 http://www.picocontainer.org/presentations/JavaPolis2003.ppt
    http://www.picocontainer.org/presentations/JavaPolis2003.pdf

    2 DIP, Robert C Martin, Bob大叔的優(yōu)秀論文
    http://www.objectmentor.com/resources/articles/dip.pdf

    3 Dependency Injection 依賴注射,Matrin Fowler對DIP的擴(kuò)展
    http://www.martinfowler.com/articles/injection.html

    4 IOC框架

    PicoContainer 優(yōu)秀的IOC框架
    http://picocontainer.org/

    Avalon
    http://avalon.apache.org/

    Spring Framework
    http://www.springframework.org/

    HiveMind
    http://jakarta.apache.org/commons/hivemind

    這篇短文基本上是改編自Martin Fowler的Inversion of Control Containers and the Dependency Injection pattern,目的呢,是讓讀者能夠在最短時(shí)間內(nèi)了解IoC的概念。這也是我一貫的“風(fēng)格”:最短的文字、最精要的內(nèi)容、最清晰的說明。希望我能做到,自勉^_^


    在J2EE應(yīng)用開發(fā)中,經(jīng)常遇到的問題就是:如何將不同的組件組裝成為一個(gè)內(nèi)聚的應(yīng)用程序?IoC模式可以解決這個(gè)問題,其目標(biāo)是將組件的配置與使用分離開。

    IoC,Inversion of Control,控制反轉(zhuǎn)[1],其原理是基于OO設(shè)計(jì)原則的The Hollywood Principle:Don't call us, we'll call you。也就是說,所有的組件[2]都是被動(dòng)的(Passive),所有的組件初始化和調(diào)用都由容器負(fù)責(zé)。組件處在一個(gè)容器當(dāng)中,由容器負(fù)責(zé)管理。

    要說明IoC模式最好的方法是使用代碼。下邊是一段正常的代碼。

       1: class ClassA...
       2:  
       3:  public String aMethod(String arg){
       4:  
       5:     String result = instanceOfClassB.bMethod();
       6:  
       7:     do something;
       8:  
       9:     return result;
      10:  
      11:  }

    在上邊的代碼里,我們要解決的問題是:ClassA如何獲得ClassB的實(shí)例?一個(gè)最直接的方法是在aMethod里聲明:

    IClassB instanceOfClassB = new ClassB();

    這里使用了一個(gè)接口IClassB。

    問題是,如果出現(xiàn)這樣的情況:繼續(xù)使用ClassA,但要求用IClassB的另一個(gè)實(shí)現(xiàn)ClassB2代替ClassB呢?更概括一點(diǎn)說:ClassA怎樣才能找到IClassB的具體實(shí)現(xiàn)?很明顯,上述代碼增加ClassA和ClassB的耦合度,以致于無法在不修改ClassA的情況下變更IClassB的具體實(shí)現(xiàn)。

    IoC模式就是用于解決這樣的問題。當(dāng)然,還有其他的方法,比如Service Locator模式,但現(xiàn)在我們只關(guān)注IoC。如前所述,IoC容器負(fù)責(zé)初始化組件(如IClassB),并將實(shí)例交給使用者。使用代碼或配置文件以聲明的方式將接口與實(shí)例關(guān)聯(lián)起來,IoC容器負(fù)責(zé)進(jìn)行實(shí)際的調(diào)用處理。對于調(diào)用者,只需要關(guān)注接口就行了。

    根據(jù)實(shí)例傳入方式的不同,IoC分為type 1 IoC(接口注入[3])、type 2 IoC(設(shè)值方法注入)和type 3 IoC(構(gòu)造子注入)。分別用代碼說明如下:

    type 1 IoC(接口注入)

       1: public interface GetClassB {
       2:  
       3:  void getClassB(IClassB instanceOfClassB);
       4:  
       5: }
       6:  
       7: class ClassA implements GetClassB…
       8:  
       9:  IClassB instanceOfClassB;
      10:  
      11:  void getClassB(IClassB instanceOfClassB) {
      12:  
      13: this.instanceOfClassB = instanceOfClassB;
      14:  
      15:  }

    type 2 IoC(設(shè)值方法注入)

       1: class ClassA...
       2:  
       3:  IClassB instanceOfClassB;
       4:  
       5:  public void setFinder(IClassB instanceOfClassB) {
       6:  
       7:     this.instanceOfClassB = instanceOfClassB;
       8:  
       9:  }

    type 3 IoC(構(gòu)造子注入)

       1: class ClassA…
       2:  
       3: ClassB instanceOfClassB;
       4:  
       5:  public classA(IClassB instanceOfClassB) {
       6:  
       7:     this. instanceOfClassB = instanceOfClassB;
       8:  
       9:  }

      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ū)別問題。我個(gè)人認(rèn)為“組件”更有助于幫助我們理解IoC的概念,所以在本文檔中使用“組件”來代表“組件或服務(wù)”

    [3] 如上所述,注入是另一種說法,此處只用于輔助說明。

    主站蜘蛛池模板: 9久久免费国产精品特黄| 免费在线精品视频| a级日本高清免费看| 亚洲AV香蕉一区区二区三区| 亚洲视频一区调教| 国产亚洲色视频在线| 亚洲成人福利在线观看| 久久亚洲精品无码播放| 国产成人精品高清免费| 国产免费久久精品99re丫y| 无码日韩精品一区二区免费暖暖| 国产产在线精品亚洲AAVV| 亚洲资源最新版在线观看| 亚洲不卡AV影片在线播放| 毛片基地免费视频a| 黄色网址免费观看| 免费无码一区二区三区| A片在线免费观看| 久久国产精品免费| 一个人免费观看日本www视频| 爱情岛亚洲论坛在线观看| 亚洲人成人网站18禁| 亚洲最大的成人网站| 亚洲13又紧又嫩又水多| 亚洲国产精品一区二区久| 1区1区3区4区产品亚洲| 亚洲精品人成在线观看| 亚洲Av永久无码精品三区在线| 亚洲中文字幕无码久久2017| 国产亚洲自拍一区| 亚洲啪啪综合AV一区| 亚洲区小说区激情区图片区| 亚洲国产精品高清久久久| 亚洲乱码中文字幕久久孕妇黑人| 久久久无码精品亚洲日韩软件 | 亚洲午夜免费视频| 亚洲AV永久精品爱情岛论坛| 亚洲免费在线视频| 亚洲激情视频网站| 亚洲成a人片在线不卡| 亚洲欧美日韩中文高清www777|