裝飾者模式解析

定義:在不改變原類文件以及不使用繼承的情況下理卑,動態(tài)地將責任附加到對象上铅歼,從而實現(xiàn)動態(tài)拓展一個對象的功能。它是通過創(chuàng)建一個包裝對象堤舒,也就是裝飾來包裹真實的對象。

裝飾者模式解決的問題

1.當我們需要為某個現(xiàn)有的對象哺呜,動態(tài)的增加一個新的功能或職責時舌缤,可以考慮使用裝飾模式。
2.當某個對象的職責經(jīng)常發(fā)生變化或者經(jīng)常需要動態(tài)的增加職責,避免為了適應(yīng)這樣的變化国撵,而增加繼承子類擴展的方式陵吸,因為這種方式會造成子類膨脹的速度過快,難以控制介牙。

裝飾者模式的優(yōu)點和缺點

優(yōu)點:1)裝飾類和被裝飾類可以獨立發(fā)展壮虫,而不會相互耦合,Component類無須知道Decorator類环础,Decorator類是從外部來擴展Component類的功能囚似,而Decorator也不用知道具體的構(gòu)件;2)裝飾模式是繼承關(guān)系的一個替代方案线得;3)我們看裝飾類Decorator饶唤,不管裝飾多少層,他始終是一個Component贯钩,實現(xiàn)的還是is-a的關(guān)系,所以他是繼承的一種良好替代方案募狂;4)如果設(shè)計得當,裝飾器類的嵌套順序可以任意,比如一定要注意前提,那就是你的裝飾不依賴順序
缺點:1)裝飾器模式雖然從數(shù)量級上減少了類的數(shù)量,但是為了要裝飾,仍舊會增加很多的小類這些具體的裝飾類的邏輯將不會非常的清晰,不夠直觀,容易令人迷惑;2)裝飾器模式雖然減少了類的爆炸,但是在使用的時候,你就可能需要更多的對象來表示繼承關(guān)系中的一個對象魏保;3)多層的裝飾是比較復(fù)雜,比如查找問題時,被層層嵌套,不容易發(fā)現(xiàn)問題所在

裝飾者模式的設(shè)計要點

  1. 多用組合熬尺,少用繼承
  2. 開閉原則:類應(yīng)該對拓展開放,對修改關(guān)閉

裝飾者模式的UML圖

裝飾者模式的一般結(jié)構(gòu)
  1. Component(抽象構(gòu)件)通常是一個抽象類或者一個接口谓罗,定義了屬性或者方法粱哼,方法的實現(xiàn)可以自己實現(xiàn),也可以由子類實現(xiàn)檩咱。通常不會直接使用Component揭措,而是通過繼承Component來實現(xiàn)特定的功能,它約束了整個繼承樹的行為刻蚯。比如說绊含,如果Component代表人,即使通過裝飾也不會使人變成別的動物炊汹。
  2. ConcreteComponent(具體構(gòu)件)是Component的子類躬充,實現(xiàn)了相應(yīng)的方法,它充當了“被裝飾者”的角色讨便。
  3. Decorator(抽象裝飾類)也是Component的子類充甚,它是裝飾者共同實現(xiàn)的抽象類(也可以是接口)。比如說霸褒,Decorator代表衣服這一類裝飾者伴找,那么它的子類可以是T恤、裙子之類的裝飾者废菱。
  4. ConcreteDecorator(具體裝飾類)是Decorator的子類技矮,是具體的裝飾者抖誉,由于它也是Component的子類,因此它能方便地拓展Component的狀態(tài)(比如添加新的方法)衰倦。每個裝飾者都應(yīng)該有一個實例變量用以保存某個Component的引用袒炉,這也是利用了組合的特性。在持有Component的引用后耿币,由于其自身也是Component的子類梳杏,那么,相當于ConcreteDecorator包裹了Component淹接,不但有Component的特性,同時自身也可以有別的特性叛溢,最終實現(xiàn)“裝飾”的效果塑悼。

裝飾者模式實例

裝飾者模式實例
抽象構(gòu)件
public abstract class Person {
    String description = "I'm a person.";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}
具體構(gòu)件
public class Teenager extends Person {
    public Teenager() {
        description = "I'm a Teenager.";
    }

    @Override
    public double cost() {
        return 0;
    }
}
抽象裝飾類
public abstract class ClothingDecorator extends Person {
    @Override
    public abstract String getDescription();
}
public abstract class HatDecorator extends Person {
    @Override
    public abstract String getDescription();
}
具體裝飾類
public class Shirt extends ClothingDecorator {
    private Person person;

    public Shirt(Person person) {
        this.person = person;
    }

    @Override
    public double cost() {
        return person.cost() + 100;
    }

    @Override
    public String getDescription() {
        return person.getDescription() + " buy a shirt";
    }
}
public class Casquette extends HatDecorator {
    private Person person;

    public Casquette(Person person) {
        this.person = person;
    }

    @Override
    public String getDescription() {
        return person.getDescription() + " buy a casquette";
    }

    @Override
    public double cost() {
        return person.cost() + 20;
    }
}
測試
public class TeenagerTest {
    public static void main(String[] args) {
        Person person = new Teenager();
        person = new Shirt(person);
        person = new Casquette(person);
        System.out.println(person.getDescription());
        System.out.println(person.cost());
    }
}
I'm a Teenager. buy a shirt buy a casquette
120.0
時序圖
時序圖

裝飾者模式與代理模式

裝飾者模式 代理模式
職能 增強對象,擴展對象功能 控制對象訪問楷掉,隱藏了控制對象的實現(xiàn)信息
實現(xiàn)接口 裝飾類和被裝飾類實現(xiàn)相同接口 代理類和委托類實現(xiàn)相同接口
使用/實現(xiàn)方式 通常做法是將原始對象作為參數(shù)傳入裝飾者的構(gòu)造器 通常在一個代理類中創(chuàng)建委托類的實例
確認時機 在運行時通過參數(shù)傳遞 編譯時確認依賴關(guān)系

無用的裝飾者模式厢蒜?

見參考文獻。

參考文獻

學(xué)習(xí)烹植、探究Java設(shè)計模式——裝飾者模式
設(shè)計模式 | 裝飾者模式及典型應(yīng)用
Java I/O系統(tǒng)----------- 類圖框架
無用的設(shè)計模式之裝飾者模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斑鸦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子草雕,更是在濱河造成了極大的恐慌巷屿,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墩虹,死亡現(xiàn)場離奇詭異嘱巾,居然都是意外死亡,警方通過查閱死者的電腦和手機诫钓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門旬昭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人菌湃,你說我怎么就攤上這事问拘。” “怎么了惧所?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵骤坐,是天一觀的道長。 經(jīng)常有香客問我纯路,道長或油,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任驰唬,我火速辦了婚禮顶岸,結(jié)果婚禮上腔彰,老公的妹妹穿的比我還像新娘。我一直安慰自己辖佣,他們只是感情好霹抛,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著卷谈,像睡著了一般杯拐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上世蔗,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天端逼,我揣著相機與錄音,去河邊找鬼污淋。 笑死顶滩,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的寸爆。 我是一名探鬼主播礁鲁,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼赁豆!你這毒婦竟也來了仅醇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤魔种,失蹤者是張志新(化名)和其女友劉穎析二,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體务嫡,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡甲抖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了心铃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片准谚。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖去扣,靈堂內(nèi)的尸體忽然破棺而出柱衔,到底是詐尸還是另有隱情,我是刑警寧澤愉棱,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布唆铐,位于F島的核電站,受9級特大地震影響奔滑,放射性物質(zhì)發(fā)生泄漏艾岂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一朋其、第九天 我趴在偏房一處隱蔽的房頂上張望王浴。 院中可真熱鬧脆炎,春花似錦、人聲如沸氓辣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钞啸。三九已至几蜻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間体斩,已是汗流浹背梭稚。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留硕勿,地道東北人哨毁。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像源武,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子想幻,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

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

  • 本篇文章介紹一種設(shè)計模式——裝飾者模式粱栖。裝飾者模式在Java中的典型應(yīng)用就是IO流,在本篇文章中將有詳細介紹脏毯。本篇...
    Ruheng閱讀 22,203評論 13 56
  • 前言 本文的主要內(nèi)容: 介紹裝飾者模式 示例 源碼分析裝飾者模式的典型應(yīng)用Java I/O 中的裝飾者模式spri...
    小旋鋒的簡書閱讀 1,257評論 0 3
  • 在《JAVA與模式》一書開頭是這樣描述裝飾(Decorator)模式的: 裝飾模式又名包裝模式闹究。裝飾模式以對客戶端...
    笨笨翔閱讀 377評論 0 2
  • 裝飾模式是一種用于替代繼承的技術(shù),它通過一種無須定義子類的方式來給對象動態(tài)增加職責食店,使用對象之間的關(guān)聯(lián)關(guān)系取代類之...
    stoneyang94閱讀 361評論 0 0
  • 設(shè)計原則: 少用繼承渣淤,多用組合 類應(yīng)該對擴展開放,對修改關(guān)閉 目錄 本文的結(jié)構(gòu)如下: 什么是裝飾者模式 為什么要用...
    w1992wishes閱讀 1,175評論 0 7