設(shè)計模式-裝飾模式

原文地址:LoveDev

裝飾模式(Decorator Pattern):也可以稱為包裝模式(Wrapper Pattern),它動態(tài)給一個對象增加額外的職責(zé),就增加對象功能來說,裝飾模式比生成子類實現(xiàn)更為靈活,它是一種對象結(jié)構(gòu)型模式。

裝飾模式是一種用于替代繼承的技術(shù),通過一種無須定義子類的方式給對象動態(tài)增加職責(zé),使用對象間的關(guān)聯(lián)關(guān)系替代繼承關(guān)系

裝飾模式
裝飾模式
  • Component(抽象組件類):具體組件類和抽象裝飾類共同父類,聲明了具體組件中需要實現(xiàn)的方法,它的引入可以使調(diào)用者以一致的方式處理未裝飾對象和裝飾對象,實現(xiàn)調(diào)用者的透明操作
  • ConcreteComponent(具體組件類):實現(xiàn)抽象組件類的聲明的方法
  • Decorator(抽象裝飾類):用于增加具體組件的職責(zé),它的子類實現(xiàn)具體職責(zé),它持有一個具體組件類的引用,通過該引用可以調(diào)用未裝飾前的方法,并通過子類擴(kuò)展該方法
  • ConcreteDecorator(具體裝飾類):給具體組件類增加新方法

平時生活中,有很多需要送禮物的時候,一個好禮物更需要好包裝來襯托,但是有時候買的禮物只有一個很丑陋的盒子,以裝飾模式實現(xiàn)包裝禮物的需求:

Component 類:

public abstract class Gift {

    /**
     * 禮物包裝
     */
    public abstract void packaging();
}

ConcreteComponent 類:

public class BirthdayGift extends Gift {
    @Override
    public void packaging() {
        LogUtils.i("包裝盒");
    }
}

Decorator 類:

public abstract class GiftPackaging extends Gift {

    private Gift gift;

    public GiftPackaging(Gift gift) {
        this.gift = gift;
    }

    public void packaging() {
        gift.packaging();
    }
}

ConcreteDecorator 類:

// 簡易包裝
public class SimplePackaging extends GiftPackaging {
    public SimplePackaging(Gift gift) {
        super(gift);
    }

    @Override
    public void packaging() {
        super.packaging();
        addColorSheet();
    }

    private void addColorSheet() {
        LogUtils.i("包彩紙");
    }
}

// 奢華包裝
public class LuxuryPackaging extends GiftPackaging {

    public LuxuryPackaging(Gift gift) {
        super(gift);
    }

    @Override
    public void packaging() {
        super.packaging();
        addColorSheet();
        addRibbon();
        addCard();
        addGiftBox();
    }


    private void addColorSheet() {
        LogUtils.i("包彩紙");
    }

    private void addRibbon() {
        LogUtils.i("加彩帶");
    }

    private void addCard() {
        LogUtils.i("加賀卡");
    }

    private void addGiftBox() {
        LogUtils.i("加禮盒");
    }
}

Client 類:

// 簡易包裝的禮物
Gift gift = new BirthdayGift();
Gift giftPackaging = new SimplePackaging(gift);
giftPackaging.packaging();

// 奢華包裝的禮物
Gift gift = new BirthdayGift();
Gift giftPackaging = new LuxuryPackaging(gift);
giftPackaging.packaging();

<h3> 透明裝飾模式 </h3>

上面實現(xiàn)的裝飾模式叫做透明裝飾模式,客戶端可以完全針對抽象編程,裝飾模式的透明性要求客戶端不應(yīng)該將對象類型聲明為具體組件類型或者具體裝飾類型,需要全部聲明為抽象組件類型,對于客戶端調(diào)用來說,具體組件對象具體裝飾對象是一樣的,沒有任何區(qū)別,可以一致處理這些對象,實現(xiàn)透明裝飾模式時,要求具體裝飾類的 operation() 方法覆蓋抽象裝飾類的 operation() 方法,除了調(diào)用具體組件類的 operation() 方法外,還需要調(diào)用新增的 addedBehavior() 方法來增加新職責(zé)。

透明模式可以對一個已裝飾的對象再進(jìn)行裝飾,獲得更復(fù)雜,功能更強(qiáng)大的對象。

<h3> 半透明裝飾模式 </h3>

有透明裝飾模式,就有對應(yīng)的半透明裝飾模式,有時我們需要單獨調(diào)用新增方法,就不得不把對象聲明為具體裝飾類型具體組件對象還是可以繼續(xù)定義為抽象組件類型,這就是半透明裝飾模式。

還是拿上面的栗子來說,如果包裝禮物只想用絲帶和彩紙包裝或者再加一個禮袋,用半透明模式就會非常方便靈活,直接調(diào)用對應(yīng)的方法就可以了,但是客戶端需要區(qū)別對待裝飾前后的對象

<h3> 優(yōu)點 </h3>

  • 利用關(guān)聯(lián)關(guān)系替代繼承關(guān)系,更加靈活,不會導(dǎo)致類個數(shù)急劇增加
  • 透明裝飾模式可以對一個對象進(jìn)行多次裝飾,通過使用不同的具體裝飾類的組合,能得到功能更加強(qiáng)大的對象
  • 具體組件類和具體裝飾類可以獨立變化,根據(jù)需求,在不變原來代碼得基礎(chǔ)上,增加這兩個類,很符合“開閉原則”

<h3> 缺點 </h3>

  • 既然是更加靈活的解決方法,出錯的幾率也隨之變大,排查錯誤的困難也跟著變大
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,744評論 3 421
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,879評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,181評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,935評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,325評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,534評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,084評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,892評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,322評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,735評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,990評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,800評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,084評論 2 375

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

  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,960評論 1 15
  • 1 場景問題# 1.1 復(fù)雜的獎金計算## 考慮這樣一個實際應(yīng)用:就是如何實現(xiàn)靈活的獎金計算。 獎金計算是相對復(fù)雜...
    七寸知架構(gòu)閱讀 4,042評論 4 67
  • 模式動機(jī) 一般有兩種方式可以實現(xiàn)給一個類或?qū)ο笤黾有袨椋?繼承機(jī)制,使用繼承機(jī)制是給現(xiàn)有類添加功能的一種有效途徑,...
    lever_xu閱讀 269評論 0 0
  • 需求 寫一個給人模擬搭配不同服飾的程序,可以給人換各種各樣的衣服褲子的形象。 初步實現(xiàn) 需求比較簡單,直接上代碼:...
    Mr丶sorrow閱讀 768評論 0 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,726評論 18 399