設(shè)計(jì)模式——裝飾者模式

《Head First 設(shè)計(jì)模式》 學(xué)習(xí)筆記鹦聪,碼云同步更新中

如有錯(cuò)誤或不足之處,請(qǐng)一定指出蒂秘,謝謝~

目錄

查看其它設(shè)計(jì)模式筆記泽本,點(diǎn)這里→設(shè)計(jì)模式筆記匯總

裝飾者模式

  • 定義:
    • 動(dòng)態(tài)地將責(zé)任附加到對(duì)象身上。若要擴(kuò)展功能姻僧,裝飾者提供了比繼承更有彈性的替代方案规丽。
  • 特點(diǎn):
    • 裝飾者和被裝飾著有共同的超類,裝飾過(guò)的對(duì)象可以替代原始對(duì)象使用
    • 可以用一個(gè)或多個(gè)裝飾者包裝一個(gè)對(duì)象
    • 裝飾者可以在所委托被裝飾者的行為之前撇贺、之后赌莺,加上自己的行為,來(lái)達(dá)到特定目的
  • 注意:
    • 這里用到繼承的目的不是“繼承行為”松嘶,而是“類型匹配”雄嚣。對(duì)象的行為來(lái)自于對(duì)象的組合。
      這并不違反之前提到的設(shè)計(jì)原則。
  • 優(yōu)點(diǎn):
    • 可以很靈活地?cái)U(kuò)展對(duì)象功能缓升,擴(kuò)展時(shí)符合“開(kāi)閉原則”
  • 缺點(diǎn):
    • 會(huì)產(chǎn)生很多對(duì)象鼓鲁,增加系統(tǒng)復(fù)雜度,加大學(xué)習(xí)理解成本
    • 使用時(shí)更容易出錯(cuò)港谊,錯(cuò)誤排查也更加困難(但結(jié)合工廠模式和生成器模式后會(huì)得到很大改善)
  • 案例
    • 咖啡價(jià)格計(jì)算程序的最初實(shí)現(xiàn):有一個(gè)咖啡的超類骇吭,所有品種的咖啡都會(huì)繼承他,并定義自己的描述和價(jià)格歧寺。
      但帶來(lái)的問(wèn)題是:不僅咖啡種類很多燥狰,當(dāng)加入不同的配料(奶,焦糖斜筐,奶泡龙致,摩卡)時(shí),又會(huì)有不一樣的價(jià)格顷链。
      如果這樣實(shí)現(xiàn)目代,會(huì)產(chǎn)生茫茫多的咖啡子類。
    • 裝飾者模式改造:
      • 一杯加香草嗤练、榛子的美式咖啡的計(jì)價(jià)過(guò)程:
        1. new一個(gè)美式咖啡對(duì)象
        2. 用香草對(duì)象裝飾它
        3. 用榛子對(duì)象裝飾它
        4. 調(diào)用cost()方法榛了,并依賴委托將配料的價(jià)格加上去
  • 代碼
/**
 * 飲料抽象超類
 **/
public abstract class Beverage {
    String description = "未知飲料";

    public String getDescription() {
        return description;
    }

    // 金額應(yīng)該用BigDecimal
    public abstract double cost();
}

/**
 * 配料裝飾者超類
 * 繼承飲料類
 **/
public abstract class CondimentDecorator extends Beverage {
    /**
     * 這里重寫的目的是約束配料類重寫獲取描述方法,
     * 最終拿到完整的描述鏈
     * 例如:“美式煞抬,香草霜大,榛子”
     */
    @Override
    public abstract String getDescription();
}

/**
 * 美式咖啡類
 */
public class Americano extends Beverage {
    public Americano() {
        description = "美式"; // 構(gòu)造方法,修改繼承自超類的description
    }

    @Override
    public double cost() {
        return 21; // 返回美式本身的價(jià)格
    }
}

/**
 * 香草配料
 **/
public class Vanilla extends CondimentDecorator {
    Beverage beverage; // 用來(lái)記錄被裝飾者

    public Vanilla(Beverage beverage) { // 構(gòu)造函數(shù)革答,被裝飾者作為參數(shù)
        this.beverage = beverage;
    }

    @Override
    public String getDescription() { // 獲取完整的描述
        return beverage.getDescription() + ", 香草";
    }

    @Override
    public double cost() { // 用被裝飾者的價(jià)格加上香草自己的價(jià)格
        return 3 + beverage.cost();
    }
}

/**
 * 榛子配料
 **/
public class Hazelnut extends CondimentDecorator {
    Beverage beverage;

    public Hazelnut(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", 榛子";
    }

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

/**
 * 測(cè)試
 */
public class Test {
    public static void main(String[] args) {
        Beverage beverage = new Americano();
        System.out.println(beverage.getDescription() + " ¥" + beverage.cost());

        Beverage beverage2 = new Americano();
        // 加香草
        beverage2 = new Vanilla(beverage2);
        // 加榛子
        beverage2 = new Hazelnut(beverage2);
        System.out.println(beverage2.getDescription() + " ¥" + beverage2.cost());
    }
}

結(jié)果
    美式 ¥21.0
    美式, 香草, 榛子 ¥29.0
  • Java中的裝飾者模式
    • java.io 包中有茫茫多的類战坤,但仔細(xì)觀察就會(huì)發(fā)現(xiàn),其中很多類都是裝飾者残拐。
      這也體現(xiàn)了裝飾者模式的缺點(diǎn):對(duì)于不明所以的人來(lái)說(shuō)途茫,大料API看起來(lái)會(huì)很困擾。
    • 感性去的話可以自己編寫一個(gè)裝飾者來(lái)裝飾io蹦骑,比如把輸入流中的所有小寫字母轉(zhuǎn)為大寫慈省。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市眠菇,隨后出現(xiàn)的幾起案子边败,更是在濱河造成了極大的恐慌,老刑警劉巖捎废,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笑窜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡登疗,警方通過(guò)查閱死者的電腦和手機(jī)排截,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門嫌蚤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人断傲,你說(shuō)我怎么就攤上這事脱吱。” “怎么了认罩?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵箱蝠,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我垦垂,道長(zhǎng)宦搬,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任劫拗,我火速辦了婚禮间校,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘页慷。我一直安慰自己憔足,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布差购。 她就那樣靜靜地躺著四瘫,像睡著了一般汉嗽。 火紅的嫁衣襯著肌膚如雪欲逃。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天饼暑,我揣著相機(jī)與錄音稳析,去河邊找鬼。 笑死弓叛,一個(gè)胖子當(dāng)著我的面吹牛彰居,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播撰筷,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼陈惰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了毕籽?” 一聲冷哼從身側(cè)響起抬闯,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎关筒,沒(méi)想到半個(gè)月后溶握,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蒸播,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年睡榆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了萍肆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胀屿,死狀恐怖塘揣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宿崭,我是刑警寧澤勿负,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站劳曹,受9級(jí)特大地震影響奴愉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铁孵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一锭硼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蜕劝,春花似錦檀头、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至婴削,卻和暖如春廊镜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背唉俗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工嗤朴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虫溜。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓雹姊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親衡楞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吱雏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355