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

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

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

    Dict.CN 在線詞典, 英語學習, 在線翻譯

    都市淘沙者

    荔枝FM Everyone can be host

    統計

    留言簿(23)

    積分與排名

    優秀學習網站

    友情連接

    閱讀排行榜

    評論排行榜

    IOC和Dependency Injection

    其實IOC模式并不是什么新的東西,它是一種很普遍的概念(或者說結構),GoF中的Template Method 就是IOC的結構。顧名思義,IOC即控制反轉。著名的好萊塢原則:“Don’t Call us, We will call you”,以及Robert C. Martin在其敏捷軟件開發中所描述的依賴倒置原則(Dependency Inversion Principle, DIP)都是這一思想的體現。Dependency InjectionMartin FlowerIOC模式的一種擴展的解釋,下面我們從一個簡單的實例開始。

    考慮一個Button來控制Lamp的開和關。

    如下的類圖,并寫下了代碼。

     

    public class Button {

           private Lamp lnkLamp;

           public void poll() {

                  lnkLamp.Turnon();

           }

    }

    但是馬上發現這個設計的問題,Button類直接依賴于Lamp類,這個依賴關系意味著當Lamp類修改時,Button類會受到影響。此外,想重用Button類來控制類似與Lamp的另外一個對象則是不可能的。即Button控制Lamp,并且只能控制Lamp

    顯然,我違反了“高層模塊不應該依賴于底層模塊,兩者都應該依賴于抽象;抽象不應該依賴于具體實現,細節應該依賴于抽象” 這一原則(DIP原則)。

    考慮到上述問題,自然地想到應該抽象出一個接口,來消除ButtonLamp的依賴,于是設計如下:


        這樣,我們倒置了
    ButtonLamp的依賴關系,使得Lamp依賴于SwitchableDevice接口,SwitchableDevice并沒有依賴于Button類,任何知道如何操縱該接口的對象都可以控制Lamp。同時Button不只是可以控制Lamp,還可以控制同樣實現SwitchableDevice接口的如ComputerCell Phone等等。回頭想想,這種做法好像似曾相識,拍拍腦袋,哦!這不是GoF策略(Strategy)模式嗎?!正是,不經意間我就應用了設計模式(有點得意哦~~~~)。

    現在再來考慮一個問題,剛才的做法雖然倒置了依賴關系,但是如果將Button作為一個應用程序來控制Lamp或者同樣實現SwitchableDeviceComputerCell Phone等,則代碼可能如下:

    public class Button {

    private SwitchableDevice lnkLamp;

    public Button(){

        lnkLamp= new Lamp();

    }

    }

    也就是說ButtonLamp之間仍然存在《creates》這樣的依賴關系。

    為了解除這種依賴關系,首先看GoF能作些什么。顯然,這個地方應該用Factory模式,將對象的創建交給Factory Class來處理,這樣雖然解開了Lamp組件與我們應用程序Button之間的耦合關系,但是組件的創建仍然是顯式的(explicitly),在組件更改時仍需要重新編譯。

    另外,通過一個ServiceLocatorlook up實現類也是一種解除耦合的辦法,看到這兒,你不禁會想EJB不就是這么實現的嘛,U are Right! Rod Johnson 在其大作J2EE without EJB中稱這種方式為Dependency Look up,但這種方式也有其弊端,比如無法脫離容器環境,以及不利于Unit test等。

    Don’t Call us, We will Call you”,這個原則啟示我們應該換一個思路,不應該在應用類中創建具體對象的實例,而是應該將具體對象實例的創建插入(plug)或者說注射(inject)到應用類中,這大概是依賴注射名稱的由來吧。

    這種實現方式需要在應用類以及調用組件之間建立一個assembler來解除兩者之間的依賴,看起來與前面的方式沒有太大區別,來看一下結構:


        仔細查看會發現還是有比較大的不同,依賴關系是相反的,也就是說這個過程中依然倒置了依賴關系。
    Lamp通過Assembler將其創建過程注射到了Button中,從而消除了兩者之間的耦合,增加了靈活性。

    下面我們看一下具體的實現,在PicoContainer以及Spring中有著其不同的實現,分別代表了兩種類型的Dependency Injection, Constructor Injection Setter Injection

    private MutablePicoContainer configureContainer() {

            MutablePicoContainer pico = new DefaultPicoContainer();

            pico.registerComponentImplementation(SwitchableDevice.class, Lamp.class);

            pico.registerComponentImplementation(Button.class);

            return pico;

    }

    然后可以通過MutablePicoContainergetComponentImplementation方法獲得實現類,調用其poll方法控制Lamp的開關,這樣一來,兩者之間的耦合通過PicoContainer提供的Assembler完全消除了。

    Spring則通過一個XML格式的配置文件,將兩者聯系起來,使用時,通過ApplicationContext獲得Button Bean,再調用其方法實現,同樣也消除了耦合關系

    posted on 2006-02-24 20:55 都市淘沙者 閱讀(915) 評論(0)  編輯  收藏 所屬分類: Spring+Struts+Hibernate

    主站蜘蛛池模板: 国产亚洲精品VA片在线播放| 亚洲av激情无码专区在线播放| 亚洲无吗在线视频| 亚洲黄色免费电影| 亚洲美女视频一区| 亚洲最大免费视频网| 亚洲婷婷在线视频| 成人片黄网站A毛片免费| 国产成人精品日本亚洲直接| 无人在线直播免费观看| 亚洲成_人网站图片| 色吊丝永久在线观看最新免费| 国产成人人综合亚洲欧美丁香花| 国产成人一区二区三区免费视频 | 亚洲综合久久综合激情久久| 免费av片在线观看网站| 亚洲精品在线电影| 成人av免费电影| 羞羞漫画页面免费入口欢迎你 | 免费成人福利视频| 亚洲色欲色欱wwW在线| 四虎永久在线精品视频免费观看| 人成电影网在线观看免费| 国产亚洲人成网站在线观看不卡| 久9久9精品免费观看| 亚洲高清一区二区三区| 亚洲国产成人a精品不卡在线| 99久久免费国产精精品| 亚洲Av无码一区二区二三区| 国产男女性潮高清免费网站| 中文字幕免费在线看| 亚洲三级在线播放| 国产啪亚洲国产精品无码| 免费看又黄又无码的网站| 亚洲av乱码一区二区三区按摩| 亚洲美日韩Av中文字幕无码久久久妻妇 | 亚洲精品无码午夜福利中文字幕 | 最近中文字幕无免费视频| 深夜福利在线免费观看| 亚洲高清美女一区二区三区| 又粗又硬又黄又爽的免费视频|