JavaEE進(jìn)階知識(shí)學(xué)習(xí)-----設(shè)計(jì)模式---裝飾者模式

定義

動(dòng)態(tài)的將責(zé)任附加到對(duì)象上,若要擴(kuò)展功能,裝飾者模式提供了比繼承更具有彈性的方案脂矫。

為什么會(huì)出現(xiàn)這個(gè)設(shè)計(jì)模式

給對(duì)象擴(kuò)展行為的方法有兩種,一種是通過繼承霉晕,繼承是給類添加擴(kuò)展行為比較有效的辦法庭再,通過使用繼承,可以使得子類有自己的行為娄昆,還可以獲得父類的行為方法佩微,但是使用繼承是靜態(tài)的,在編譯的時(shí)候就已經(jīng)決定了子類有哪些行為萌焰。
當(dāng)然還可以使用關(guān)聯(lián)哺眯,將一個(gè)對(duì)象嵌入到另一個(gè)對(duì)象中,有一個(gè)對(duì)象來決定是否引用該對(duì)象來擴(kuò)展自己的行為扒俯,這是一種動(dòng)態(tài)的方式奶卓,我們可以在程序中動(dòng)態(tài)的決定和控制。
前面所說的兩種都會(huì)導(dǎo)致一種‘類爆炸’的情況出現(xiàn)撼玄,所以就出現(xiàn)了裝飾者模式夺姑。

認(rèn)識(shí)裝飾者模式

例如為咖啡店設(shè)計(jì)一個(gè)點(diǎn)咖啡的程序,采用飲料為主體掌猛,在運(yùn)行時(shí)以調(diào)料來‘裝飾’飲料盏浙,如果顧客要摩卡和奶泡深焙咖啡,那么,

  1. 拿一個(gè)深焙咖啡(DarkRoast)對(duì)象
  2. 以摩卡(Mocha)對(duì)象裝飾它
  3. 一奶泡(Whip)對(duì)象裝飾它
  4. 調(diào)用cost方法废膘,并依賴委托(delegate)將調(diào)料的錢加上去竹海。

裝飾者類圖結(jié)構(gòu)

image

實(shí)現(xiàn)裝飾者模式

情景:購(gòu)買咖啡時(shí)丐黄,會(huì)加入不同的調(diào)料斋配,根據(jù)不同的調(diào)料來收費(fèi)灌闺,也就是說不同的咖啡與不同的調(diào)料有N中不同的組合方式,也就是出現(xiàn)了不同組合就應(yīng)該有不同的價(jià)格桂对。結(jié)構(gòu)圖如下:

image

代碼實(shí)現(xiàn)

Beverage組件基類

public abstract class Beverage {
    protected String description = "";
    public String getDescription() {
        return description;
    }
    public abstract double cost();

}

HouseBlend組件

public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "這是一杯綜合咖啡";
    }
    @Override
    public double cost() {
        return 0.89;
    }

}

Espresso組件

public class Espresso extends Beverage{
    public Espresso() {
        description = "這是一杯濃縮咖啡";
    }
    @Override
    public double cost() {
        return 1.99;
    }

}

Decat組件

public class Decat extends Beverage {
    public Decat() {
        description = "這是一杯深焙咖啡";
    }
    @Override
    public double cost() {
        return 0.99;
    }

}

DarkRoast

public class DarkRoast extends Beverage{
    public DarkRoast() {
        description = "這是一杯低咖啡因咖啡";
    }
    @Override
    public double cost() {
        return 1.05;
    }

}

配料基本類

public abstract class CondimentDecorator extends Beverage{
    public abstract String getDescription();
}

Milk配料

public class Milk extends CondimentDecorator{
    Beverage beverage;
    public Milk(Beverage beverage) {
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        return beverage.getDescription()+",牛奶";
    }

    @Override
    public double cost() {
        return beverage.cost()+0.1;
    }

}

Mocha配料

public class Mocha extends CondimentDecorator {
    Beverage beverage;
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        return beverage.getDescription()+",摩卡";
    }

    @Override
    public double cost() {
        return beverage.cost()+0.2;
    }

}

Soy配料

public class Soy extends CondimentDecorator{
    Beverage beverage;
    public Soy(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription()+",豆?jié){";
    }

    @Override
    public double cost() {
        return beverage.cost()+0.15;
    }

}

Whip配料

public class Whip extends CondimentDecorator{
    Beverage beverage;
    public Whip(Beverage beverage) {
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        return beverage.getDescription()+",奶泡";
    }

    @Override
    public double cost() {
        return beverage.cost()+0.1;
    }

}

測(cè)試類

public class StartbuzzCoffee {
    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription()+",$"+beverage.cost());
        System.out.println("========================");
        
        Beverage beverage2 = new DarkRoast();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription()+",$"+beverage2.cost());
    }

}

測(cè)試結(jié)果

這是一杯濃縮咖啡,$1.99
========================
這是一杯低咖啡因咖啡,摩卡,摩卡,奶泡,$1.55

總結(jié)

  1. 裝飾者可以提供比繼承更多的靈活性嵌器。
  2. 可以通過一種動(dòng)態(tài)的方式來擴(kuò)展一個(gè)對(duì)象的功能五芝,在運(yùn)行時(shí)選擇不同的的裝飾器狮崩,從而實(shí)現(xiàn)不同的行為蛛勉。
  3. 具體組件類和裝飾類可以獨(dú)立變化,用戶可以根據(jù)自己的需要增加具體的組件類和裝飾類睦柴,原有的代碼無需改變诽凌,負(fù)荷”開閉原則“。
  4. 但是也會(huì)產(chǎn)生很多的小對(duì)象侣诵,增加了系統(tǒng)的負(fù)責(zé)性狱窘。
  5. 建議在不影響其他對(duì)象的時(shí)候使用,以動(dòng)態(tài)蘸炸,透明的方式給單個(gè)對(duì)象添加職責(zé)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末穷当,一起剝皮案震驚了整個(gè)濱河市淹禾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铃岔,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件智嚷,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡纤勒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門粹湃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泉坐,“玉大人,你說我怎么就攤上這事孤钦。” “怎么了偏形?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵觉鼻,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我坠陈,道長(zhǎng),這世上最難降的妖魔是什么庸蔼? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任贮匕,我火速辦了婚禮,結(jié)果婚禮上粗合,老公的妹妹穿的比我還像新娘。我一直安慰自己壤追,他們只是感情好供屉,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布溺蕉。 她就那樣靜靜地躺著悼做,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漓雅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天邻吞,我揣著相機(jī)與錄音葫男,去河邊找鬼。 笑死梢褐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的耿眉。 我是一名探鬼主播猪贪,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼讯私,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了桶癣?” 一聲冷哼從身側(cè)響起娘锁,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎莫秆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惹挟,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缝驳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年归苍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了运怖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吻氧,死狀恐怖咏连,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捻勉,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布报账,位于F島的核電站埠偿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏冠蒋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一朽寞、第九天 我趴在偏房一處隱蔽的房頂上張望斩郎。 院中可真熱鬧,春花似錦缩宜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匣沼。三九已至乃秀,卻和暖如春圆兵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背殉农。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工局荚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耀态。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓首装,卻偏偏與公主長(zhǎng)得像创夜,于是被迫代替她去往敵國(guó)和親仙逻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

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

  • 裝飾者模式可以做到在不修改任何底層代碼的情況下檬贰,給對(duì)象增加的新的方法缺亮。首先,我們通過對(duì)一個(gè)現(xiàn)實(shí)問題的模擬分析萌踱,了解...
    六尺帳篷閱讀 883評(píng)論 0 9
  • 1 場(chǎng)景問題# 1.1 復(fù)雜的獎(jiǎng)金計(jì)算## 考慮這樣一個(gè)實(shí)際應(yīng)用:就是如何實(shí)現(xiàn)靈活的獎(jiǎng)金計(jì)算虫蝶。 獎(jiǎng)金計(jì)算是相對(duì)復(fù)雜...
    七寸知架構(gòu)閱讀 4,013評(píng)論 4 67
  • 前言 距離上一篇,間隔時(shí)間有點(diǎn)長(zhǎng)哈(尷尬 ==!)經(jīng)歷過漫長(zhǎng)的實(shí)習(xí)期,試用期扰柠,第一份工作終于慢慢走上正軌,中間發(fā)生...
    暗影飛客閱讀 1,183評(píng)論 0 0
  • 設(shè)計(jì)原則: 少用繼承蝙泼,多用組合 類應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉 目錄 本文的結(jié)構(gòu)如下: 什么是裝飾者模式 為什么要用...
    w1992wishes閱讀 1,189評(píng)論 0 7
  • 一直不太懂得網(wǎng)戀的意義 直到我遇到你 一個(gè)經(jīng)歷了蘇武牧羊的悲戚 ...
    檻外者閱讀 215評(píng)論 0 0