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

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

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

    海鷗航際

    JAVA站
    posts - 11, comments - 53, trackbacks - 1, articles - 102

    Ioc模式解析

    Posted on 2005-01-14 20:22 海天一鷗 閱讀(339) 評(píng)論(0)  編輯  收藏 所屬分類: J2EE
    分離關(guān)注( Separation of Concerns : SOC)是Ioc模式和AOP產(chǎn)生最原始動(dòng)力,通過功能分解可得到關(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)的,也就是如下語句遲早要執(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)語句表明當(dāng)前是在調(diào)用被調(diào)用者AInterfaceImp,由于被調(diào)用者名稱寫入了調(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


      有過EJB開發(fā)經(jīng)驗(yàn)的人都知道,每個(gè)EJB的調(diào)用都需要通過JNDI尋找到工廠性質(zhì)的Home接口,在我的教程EJB是什么章節(jié)中,我也是從依賴和工廠模式角度來闡述EJB的使用。

      在通常傳統(tǒng)情況下,為了實(shí)現(xiàn)調(diào)用者和被調(diào)用者解耦,分離,一般是通過工廠模式實(shí)現(xiàn)的,下面將通過比較工廠模式和Ioc模式不同,加深理解Ioc模式。

        工廠模式和Ioc

      假設(shè)有兩個(gè)類B 和 C:B作為調(diào)用者,C是被調(diào)用者,在B代碼中存在對(duì)C的調(diào)用:

    public class B{    private C comp;   ...... }


      實(shí)現(xiàn)comp實(shí)例有兩種途徑:?jiǎn)螒B(tài)工廠模式和Ioc。

        工廠模式實(shí)現(xiàn)如下:

    public class B{    private C comp;   private final static MyFactory myFactory = MyFactory.getInstance();   public B(){     this.comp = myFactory.createInstanceOfC();   }    public void someMethod(){     this.comp.sayHello();   }   ...... }


        特點(diǎn):
        每次運(yùn)行時(shí),MyFactory可根據(jù)配置文件XML中定義的C子類實(shí)現(xiàn),通過createInstanceOfC()生成C的具體實(shí)例。

        使用Ioc依賴性注射( Dependency Injection )實(shí)現(xiàn)Picocontainer如下,B類如同通常POJO類,如下:

    public class B{    private C comp;   public B(C comp){     this.comp = comp;    }    public void someMethod(){     this.comp.sayHello();    }   ...... }


        假設(shè)C接口/類有有一個(gè)具體實(shí)現(xiàn)CImp類。當(dāng)客戶端調(diào)用B時(shí),使用下列代碼:

    public class client{    public static void main( String[] args ) {     DefaultPicoContainer container = new DefaultPicoContainer();     container.registerComponentImplementation(CImp.class);     container.registerComponentImplementation(B.class);     B b = (B) container.getComponentInstance(B.class);     b.someMethod();    } }


      因此,當(dāng)客戶端調(diào)用B時(shí),分別使用工廠模式和Ioc有不同的特點(diǎn)和區(qū)別:

      主要區(qū)別體現(xiàn)在B類的代碼,如果使用Ioc,在B類代碼中將不需要嵌入任何工廠模式等的代碼,因?yàn)檫@些工廠模式其實(shí)還是與C有些間接的聯(lián)系,這樣,使用Ioc徹底解耦了B和C之間的聯(lián)系。

      使用Ioc帶來的代價(jià)是:需要在客戶端或其它某處進(jìn)行B和C之間聯(lián)系的組裝。

      所以,Ioc并沒有消除B和C之間這樣的聯(lián)系,只是轉(zhuǎn)移了這種聯(lián)系。

      這種聯(lián)系轉(zhuǎn)移實(shí)際也是一種分離關(guān)注,它的影響巨大,它提供了AOP實(shí)現(xiàn)的可能。

        Ioc和AOP

      AOP我們已經(jīng)知道是一種面向切面的編程方式,由于Ioc解放自由了B類,而且可以向B類實(shí)現(xiàn)注射C類具體實(shí)現(xiàn),如果把B類想像成運(yùn)行時(shí)的橫向動(dòng)作,無疑注入C類子類就是AOP中的一種Advice,如下圖:



      通過下列代碼說明如何使用Picocontainer實(shí)現(xiàn)AOP,該例程主要實(shí)現(xiàn)是記錄logger功能,通過Picocontainer可以使用簡(jiǎn)單一行,使所有的應(yīng)用類的記錄功能激活。

        首先編制一個(gè)記錄接口:

    public interface Logging {   public void enableLogging(Log log); }


        有一個(gè)LogSwitcher類,主要用來激活具體應(yīng)用中的記錄功能:

    import org.apache.commons.logging.Log; public class LogSwitcher {   protected Log m_log;   public void enableLogging(Log log) {     m_log = log;     m_log.info("Logging Enabled");   } }


        一般的普通應(yīng)用JavaBeans都可以繼承這個(gè)類,假設(shè)PicoUserManager是一個(gè)用戶管理類,代碼如下:

    public class PicoUserManager extends LogSwitcher {   ..... //用戶管理功能 } public class PicoXXXX1Manager extends LogSwitcher {   ..... //業(yè)務(wù)功能 } public class PicoXXXX2Manager extends LogSwitcher {   ..... //業(yè)務(wù)功能 }


        注意LogSwitcher中Log實(shí)例是由外界賦予的,也就是說即將被外界注射進(jìn)入,下面看看使用Picocontainer是如何注射Log的具體實(shí)例的。

    DefaultPicoContainer container = new DefaultPicoContainer(); container.registerComponentImplementation(PicoUserManager.class); container.registerComponentImplementation(PicoXXXX1Manager.class); container.registerComponentImplementation(PicoXXXX2Manager.class); ..... Logging logging = (Logging) container.getComponentMulticaster(); logging.enableLogging(new SimpleLog("pico"));//激活log


      由上代碼可見,通過使用簡(jiǎn)單一行l(wèi)ogging.enableLogging()方法使所有的應(yīng)用類的記錄功能激活。這是不是類似AOP的advice實(shí)現(xiàn)?

      總之,使用Ioc模式,可以不管將來具體實(shí)現(xiàn),完全在一個(gè)抽象層次進(jìn)行描述和技術(shù)架構(gòu),因此,Ioc模式可以為容器、框架之類的軟件實(shí)現(xiàn)提供了具體的實(shí)現(xiàn)手段,屬于架構(gòu)技術(shù)中一種重要的模式應(yīng)用。J道的JdonSD框架也使用了Ioc模式。
    主站蜘蛛池模板: 国产一级一片免费播放| 内射少妇36P亚洲区| 国产成A人亚洲精V品无码| 一级做a毛片免费视频| 亚洲国产精品人人做人人爽| 色屁屁在线观看视频免费| 一级毛片aaaaaa免费看| 久久久亚洲精品无码| 99re在线视频免费观看| 亚洲精品视频观看| 中字幕视频在线永久在线观看免费| 亚洲第一成人在线| 国产成人在线观看免费网站| 高清免费久久午夜精品| 亚洲国产精品高清久久久| 四虎成人精品永久免费AV| 4480yy私人影院亚洲| 日本免费xxxx| 日韩国产精品亚洲а∨天堂免| 免费在线观看理论片| 三年片免费观看大全国语| 亚洲资源在线观看| 成人免费视频网址| www永久免费视频| 亚洲午夜久久影院| 免费观看男人免费桶女人视频| 一区二区三区免费视频网站| 久久99国产亚洲高清观看首页| 97碰公开在线观看免费视频| 老司机亚洲精品影院在线观看| 亚洲女初尝黑人巨高清| 99在线精品免费视频九九视| 国产亚洲美女精品久久久久| 久久亚洲国产中v天仙www | 十八禁无码免费网站| 久久亚洲精品国产亚洲老地址| 亚洲福利中文字幕在线网址| 毛片免费全部播放无码| 美女免费视频一区二区| 国产成人无码综合亚洲日韩| 在线a毛片免费视频观看|