面向?qū)ο缶幊讨蕾嚨怪迷瓌t

依賴倒置原則英文全稱是Dependence Inversion Principle莹汤,縮寫是DIP崭放。依賴倒置原則指代了一種特定解耦形式锌介,使得高層次的模塊不依賴于低層次的模塊的實現(xiàn)細(xì)節(jié)的目的巾表,依賴模塊被顛倒了猛计。這到底是什么意思呢?

依賴倒置原則則有以下關(guān)鍵點:

  • 高層模塊不應(yīng)該依賴底層模塊绵估,兩者都應(yīng)該依賴其抽象炎疆;
  • 抽象不應(yīng)該依賴細(xì)節(jié)。
  • 細(xì)節(jié)應(yīng)該依賴抽象国裳。

在Java語言中形入,抽象就是指接口或抽象類,兩者都是不能直接被實例化的缝左;細(xì)節(jié)就是實現(xiàn)類亿遂,實現(xiàn)接口或者繼承抽象類而產(chǎn)生的類就是細(xì)節(jié)螟蒸,其特點就是,可以直接被實例化崩掘,也就是可以加上關(guān)鍵字new產(chǎn)生的對象七嫌。高層模塊就是調(diào)用端,底層模塊就是具體實現(xiàn)類苞慢。

依賴倒置原則在Java語言中的表現(xiàn)就是:模塊間的依賴通過抽象發(fā)生诵原,實現(xiàn)類之間不發(fā)生直接的依賴關(guān)系,其依賴關(guān)系是通過接口或者抽象類產(chǎn)生的挽放。概況為一句話就是:面向接口編程绍赛,或者說是面向抽象編程,這里的抽象只得就是接口或抽象類辑畦。面向接口是面向?qū)ο蟮木柚弧?/p>

如果類與類直接依賴于細(xì)節(jié)吗蚌,那么他們之間就有直接的耦合,當(dāng)具體實現(xiàn)需要變化時纯出,意味著需要同時修改依賴者的代碼蚯妇,這限制了系統(tǒng)的可擴(kuò)展性。

在前面的面向?qū)ο缶幊讨_閉原則這一節(jié)中暂筝,ImageLoader直接依賴于MemoryCache箩言,這個MemoryCache事一個具體實現(xiàn),而不是一個抽象類或者接口焕襟。這就導(dǎo)致了ImageLoader直接依賴了具體的細(xì)節(jié)陨收,當(dāng)MemoryCache不能滿足ImageLoader而需要被其他緩存實現(xiàn)替換時,此時就必須修改ImageLoader的代碼:

public class ImageLoader {

    /**
     * 圖片緩存
     */
    MemoryCache mMemoryCache = new MemoryCache();

    /**
     * 顯示圖片
     * @param url
     * @param imageView
     */
    public void displayImage(final String url, final ImageView imageView) {
        //判斷使用哪種緩存
        Bitmap bitmap =   mMemoryCache.get(url);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return ;
        }

        dowloadImage(url,imageView);
}

隨著產(chǎn)品的升級鸵赖,用戶發(fā)現(xiàn)MemoryCache以及不能滿足需求务漩,用戶需要小民的ImageLoader可以將圖片同時緩存到內(nèi)存和SD卡中,或者可以讓用戶自定義實現(xiàn)緩存它褪。此時饵骨,我們的 MemoryCache這個類名不僅不能夠表達(dá)內(nèi)存緩存和SD卡緩存的意義,也不能滿足功能列赎。另外宏悦,用戶需要自定義緩存實現(xiàn)時還必須繼承自MemoryCache镐确,而用戶的緩存實現(xiàn)可不一定與內(nèi)存緩存有關(guān)包吝,這在命名上的限制也讓用戶體驗不好。重構(gòu)的時候到了源葫!第一種方案是將MemoryCache修改為DoubleCache诗越,然后在DoubleCache中實現(xiàn)具體的緩存功能。我們需要將ImageLoader修改如下:

public class ImageLoader {

    /**
     * 圖片緩存
     */
    DoubleCache mDoubleCache = new DoubleCache();

    /**
     * 顯示圖片
     * @param url
     * @param imageView
     */
    public void displayImage(final String url, final ImageView imageView) {
        //判斷使用哪種緩存
        Bitmap bitmap =   mDoubleCache.get(url);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return ;
        }

        dowloadImage(url,imageView);
}

在程序中我們將MemoryCache修改成DoubleCache息堂,然后修改了ImageLoader中緩存類的具體實現(xiàn)嚷狞,輕輕松松就滿足了用戶需求块促。這不還是依賴具體的實現(xiàn)類嗎?當(dāng)用戶的需求發(fā)生變化時床未,我們又要通過修改緩存實現(xiàn)類和ImageLoader代碼來實現(xiàn)竭翠?

針對這些問題,給出的解決方案就要能夠讓緩存系統(tǒng)更加靈活薇搁。一句話概括起來就是:依賴抽象斋扰,而不是依賴具體實現(xiàn)。針對圖片緩存啃洋,建立ImageCache抽象(開閉原則小節(jié)所述)传货,該抽象增加了get和put方法用以實現(xiàn)圖片的存取。每種緩存實現(xiàn)都必須實現(xiàn)這個接口宏娄,并且實現(xiàn)自己的存取方法问裕。當(dāng)用戶需要使用不同的緩存實現(xiàn)時,直接通過依賴注入即可孵坚,保證了系統(tǒng)的靈活性粮宛。我們來回顧一下相關(guān)代碼:

ImageCache緩存接口類:

public interface ImageCache {

    /**
     * 獲取圖片
     * @param url
     * @return
     */
    public Bitmap get(String url);

    /**
     * 緩存圖片
     * @param url
     * @param bitmap
     */
    public void put(String url, Bitmap bitmap);
}

ImageLoader類:

public class ImageLoader {

    /**
     * 圖片緩存
     */
    ImageCache mImageCache = new MemoryCache();

    /**
     * 注入緩存實現(xiàn)
     * @param cache
     */
    public void setIamgeCache(ImageCache cache) {
        mImageCache = cache;
    }

    public void displayImage(final String url, final ImageView imageView) {
        //判斷使用哪種緩存
        Bitmap bitmap =   mImageCache.get(url);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return ;
        }

        dowloadImage(url,imageView);

在這里,我們建立了ImageCache抽象類卖宠,并且讓ImageLoader依賴于抽象而不是具體細(xì)節(jié)窟勃。當(dāng)需求發(fā)生變化時,只要實現(xiàn)ImageCache類或者繼承其他已有的ImageCache子類完成相應(yīng)的緩存功能逗堵,然后將具體的實現(xiàn)類注入到ImageLoader即可實現(xiàn)緩存功能的替換秉氧,這就保證的緩存系統(tǒng)的高可擴(kuò)展性,有了擁抱變化的能力蜒秤,這就是依賴倒置原則汁咏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市作媚,隨后出現(xiàn)的幾起案子攘滩,更是在濱河造成了極大的恐慌,老刑警劉巖纸泡,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漂问,死亡現(xiàn)場離奇詭異,居然都是意外死亡女揭,警方通過查閱死者的電腦和手機(jī)蚤假,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吧兔,“玉大人闲询,你說我怎么就攤上這事瓢姻∫迹” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵伺通,是天一觀的道長。 經(jīng)常有香客問我逢享,道長罐监,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任瞒爬,我火速辦了婚禮笑诅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疮鲫。我一直安慰自己吆你,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布俊犯。 她就那樣靜靜地躺著妇多,像睡著了一般。 火紅的嫁衣襯著肌膚如雪燕侠。 梳的紋絲不亂的頭發(fā)上者祖,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天,我揣著相機(jī)與錄音绢彤,去河邊找鬼七问。 笑死,一個胖子當(dāng)著我的面吹牛茫舶,可吹牛的內(nèi)容都是我干的械巡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饶氏,長吁一口氣:“原來是場噩夢啊……” “哼讥耗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起疹启,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤古程,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后喊崖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挣磨,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年荤懂,在試婚紗的時候發(fā)現(xiàn)自己被綠了茁裙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡势誊,死狀恐怖呜达,靈堂內(nèi)的尸體忽然破棺而出谣蠢,到底是詐尸還是另有隱情粟耻,我是刑警寧澤查近,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站挤忙,受9級特大地震影響霜威,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜册烈,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一戈泼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赏僧,春花似錦大猛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至驾中,卻和暖如春唉堪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肩民。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工唠亚, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人持痰。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓灶搜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親工窍。 傳聞我的和親對象是個殘疾皇子占调,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容