<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 海天一鷗 閱讀(340) 評論(0)  編輯  收藏 所屬分類: J2EE
    分離關注( 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的調用:

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


      實現comp實例有兩種途徑:單態工廠模式和Ioc。

        工廠模式實現如下:

    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();   }   ...... }


        特點:
        每次運行時,MyFactory可根據配置文件XML中定義的C子類實現,通過createInstanceOfC()生成C的具體實例。

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

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


        假設C接口/類有有一個具體實現CImp類。當客戶端調用B時,使用下列代碼:

    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();    } }


      因此,當客戶端調用B時,分別使用工廠模式和Ioc有不同的特點和區別:

      主要區別體現在B類的代碼,如果使用Ioc,在B類代碼中將不需要嵌入任何工廠模式等的代碼,因為這些工廠模式其實還是與C有些間接的聯系,這樣,使用Ioc徹底解耦了B和C之間的聯系。

      使用Ioc帶來的代價是:需要在客戶端或其它某處進行B和C之間聯系的組裝。

      所以,Ioc并沒有消除B和C之間這樣的聯系,只是轉移了這種聯系。

      這種聯系轉移實際也是一種分離關注,它的影響巨大,它提供了AOP實現的可能。

        Ioc和AOP

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



      通過下列代碼說明如何使用Picocontainer實現AOP,該例程主要實現是記錄logger功能,通過Picocontainer可以使用簡單一行,使所有的應用類的記錄功能激活。

        首先編制一個記錄接口:

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


        有一個LogSwitcher類,主要用來激活具體應用中的記錄功能:

    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");   } }


        一般的普通應用JavaBeans都可以繼承這個類,假設PicoUserManager是一個用戶管理類,代碼如下:

    public class PicoUserManager extends LogSwitcher {   ..... //用戶管理功能 } public class PicoXXXX1Manager extends LogSwitcher {   ..... //業務功能 } public class PicoXXXX2Manager extends LogSwitcher {   ..... //業務功能 }


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

    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


      由上代碼可見,通過使用簡單一行logging.enableLogging()方法使所有的應用類的記錄功能激活。這是不是類似AOP的advice實現?

      總之,使用Ioc模式,可以不管將來具體實現,完全在一個抽象層次進行描述和技術架構,因此,Ioc模式可以為容器、框架之類的軟件實現提供了具體的實現手段,屬于架構技術中一種重要的模式應用。J道的JdonSD框架也使用了Ioc模式。
    主站蜘蛛池模板: **aaaaa毛片免费同男同女| 国产一区二区免费在线| 亚洲中文字幕无码亚洲成A人片| 国产精品免费视频一区| 青柠影视在线观看免费| 亚洲最大天堂无码精品区| 亚洲精品成人网久久久久久| 久久国产免费观看精品3| 亚洲国产精品无码久久久秋霞1| 亚洲色中文字幕无码AV| 日韩精品成人无码专区免费| 免费国产a理论片| 久久久久亚洲精品无码蜜桃| 天堂亚洲免费视频| 国产91色综合久久免费| 日韩少妇内射免费播放| 亚洲人成在久久综合网站| 亚洲成?v人片天堂网无码| 免费观看激色视频网站bd| 久草免费福利在线| 亚洲一区二区三区乱码在线欧洲| 久久久久亚洲精品中文字幕| 国产va免费精品观看精品 | 亚洲国产精品成人综合久久久 | 亚洲天天在线日亚洲洲精| 国产成人无码区免费A∨视频网站 国产成人涩涩涩视频在线观看免费 | 免费99精品国产自在现线| 免费无码又爽又刺激网站直播| 亚洲av无码有乱码在线观看| 亚洲精品美女久久久久9999| 亚洲中文字幕在线观看| 麻豆精品国产免费观看| 国产成人精品免费视| 久久一区二区三区免费播放| jizz免费在线观看| 亚洲爆乳大丰满无码专区| 亚洲综合久久一本伊伊区| 久久精品国产亚洲AV高清热| 亚洲av午夜成人片精品网站 | 亚洲AV无码AV日韩AV网站| 亚洲粉嫩美白在线|