裝飾模式

描述

????裝飾模式(Decorator Pattern)又名包裝(Wrapper)模式。裝飾模式以對客戶端透明的方式擴(kuò)展對象的功能悍引,是繼承關(guān)系的一個替代方案恩脂。可以在不改變現(xiàn)有對象的結(jié)構(gòu)的情況下趣斤,動態(tài)地擴(kuò)展其功能俩块。

簡介

????這種模式創(chuàng)建了一個裝飾類,用來包裝原有的類浓领,并在保持類方法簽名完整性的前提下玉凯,提供了額外的功能。換言之联贩,客戶端并不會覺得對象在裝飾前和裝飾后有什么不同漫仆。裝飾模式可以在不使用創(chuàng)造更多子類的情況下,將對象的功能加以擴(kuò)展泪幌。


裝飾模式類圖

????如果只有一個ConcreteComponent類盲厌,那么可以考慮去掉抽象的Component類(接口),把Decorator作為一個ConcreteComponent子類祸泪。


只有一個ConcreteComponent類

????如果只有一個ConcreteDecorator類吗浩,那么就沒有必要建立一個單獨(dú)的Decorator類,而可以把Decorator和ConcreteDecorator的責(zé)任合并成一個類没隘。甚至在只有兩個ConcreteDecorator類的情況下懂扼,都可以這樣做。
只有一個ConcreteDecorator類

角色

  • 抽象構(gòu)件(Component)角色:給出一個抽象接口右蒲,以規(guī)范準(zhǔn)備接收附加責(zé)任的對象微王。
  • 具體構(gòu)件(ConcreteComponent)角色:定義一個將要接收附加責(zé)任的類。
  • 裝飾(Decorator)角色:持有一個構(gòu)件(Component)對象的實例品嚣,并定義一個與抽象構(gòu)件接口一致的接口炕倘。
  • 具體裝飾(ConcreteDecorator)角色:負(fù)責(zé)給構(gòu)件對象“貼上”附加的責(zé)任。

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 裝飾模式與繼承關(guān)系的目的都是要擴(kuò)展對象的功能翰撑,但是裝飾模式可以提供比繼承更多的靈活性罩旋。裝飾模式允許系統(tǒng)動態(tài)決定“貼上”一個需要的“裝飾”啊央,或者除掉一個不需要的“裝飾”。繼承關(guān)系則不同涨醋,繼承關(guān)系是靜態(tài)的瓜饥,它在系統(tǒng)運(yùn)行前就決定了。
  • 通過使用不同的具體裝飾類以及這些裝飾類的排列組合浴骂,設(shè)計師可以創(chuàng)造出很多不同行為的組合乓土。

缺點(diǎn)

  • 使用裝飾模式會產(chǎn)生比使用繼承關(guān)系更多的對象。更多的對象會使得查錯變得困難溯警,特別是這些對象看上去都很相像趣苏。

使用場景

  • 當(dāng)需要給一個現(xiàn)有類添加附加職責(zé),而又不能采用生成子類的方法進(jìn)行擴(kuò)充時梯轻。例如食磕,該類被隱藏或者該類是終極類或者采用繼承方式會產(chǎn)生大量的子類。
  • 當(dāng)需要通過對現(xiàn)有的一組基本功能進(jìn)行排列組合而產(chǎn)生非常多的功能時喳挑,采用繼承關(guān)系很難實現(xiàn)彬伦,而采用裝飾模式卻很好實現(xiàn)。
  • 當(dāng)對象的功能要求可以動態(tài)地添加伊诵,也可以再動態(tài)地撤銷時单绑。

示例

/**
* 抽象構(gòu)件(Component)角色
*/
public interface Shape {
    void draw();
}
/**
* 具體構(gòu)件(ConcreteComponent)角色
*/
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape: Circle");
    }
}
/**
* 具體構(gòu)件(ConcreteComponent)角色
*/
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape: Rectangle");
    }
}
/**
* 裝飾(Decorator)角色
*/
public abstract class ShapeDecorator implements Shape {
    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape) {
        this.decoratedShape = decoratedShape;
    }

    @Override
    public void draw() {
        decoratedShape.draw();
    }
}
/**
* 具體裝飾(ConcreteDecorator)角色
*/
public class RedShapeDecorator extends ShapeDecorator {
    public RedShapeDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        decoratedShape.draw();
        setRedBorder(decoratedShape);
    }

    private void setRedBorder(Shape decoratedShape) {
        System.out.println("Border Color: Red");
    }
}
/**
* 具體裝飾(ConcreteDecorator)角色
*/
public class YellowShapeDecorator extends ShapeDecorator {
    public YellowShapeDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        decoratedShape.draw();
        setRedBorder(decoratedShape);
    }

    private void setRedBorder(Shape decoratedShape) {
        System.out.println("Border Color: Yellow");
    }
}

public class DecoratorPatternDemo {
    public static void main(String[] args) {
        Shape circle = new Circle();
        ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
        ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
        ShapeDecorator yellowCircle = new YellowShapeDecorator(new Circle());
        ShapeDecorator yellowRectangle = new YellowShapeDecorator(new Rectangle());
        System.out.println("Circle with normal border");
        circle.draw();

        System.out.println("\nCircle of red border");
        redCircle.draw();

        System.out.println("\nRectangle of red border");
        redRectangle.draw();

        System.out.println("\nCircle of yellow border");
        yellowCircle.draw();

        System.out.println("\nRectangle of yellow border");
        yellowRectangle.draw();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市曹宴,隨后出現(xiàn)的幾起案子询张,更是在濱河造成了極大的恐慌,老刑警劉巖浙炼,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件份氧,死亡現(xiàn)場離奇詭異,居然都是意外死亡弯屈,警方通過查閱死者的電腦和手機(jī)蜗帜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來资厉,“玉大人厅缺,你說我怎么就攤上這事⊙绯ィ” “怎么了湘捎?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長窄刘。 經(jīng)常有香客問我窥妇,道長,這世上最難降的妖魔是什么娩践? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任活翩,我火速辦了婚禮烹骨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘材泄。我一直安慰自己沮焕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布拉宗。 她就那樣靜靜地躺著峦树,像睡著了一般。 火紅的嫁衣襯著肌膚如雪旦事。 梳的紋絲不亂的頭發(fā)上魁巩,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機(jī)與錄音族檬,去河邊找鬼歪赢。 笑死化戳,一個胖子當(dāng)著我的面吹牛单料,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播点楼,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼扫尖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掠廓?” 一聲冷哼從身側(cè)響起换怖,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蟀瞧,沒想到半個月后沉颂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悦污,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年铸屉,在試婚紗的時候發(fā)現(xiàn)自己被綠了切端。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彻坛。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖踏枣,靈堂內(nèi)的尸體忽然破棺而出茵瀑,到底是詐尸還是另有隱情马昨,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站昌阿,受9級特大地震影響恳邀,放射性物質(zhì)發(fā)生泄漏懦冰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一谣沸、第九天 我趴在偏房一處隱蔽的房頂上張望刷钢。 院中可真熱鬧,春花似錦乳附、人聲如沸内地。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阱缓。三九已至,卻和暖如春举农,著一層夾襖步出監(jiān)牢的瞬間荆针,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工颁糟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留航背,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓棱貌,卻偏偏與公主長得像玖媚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子键畴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

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

  • 【學(xué)習(xí)難度:★★★☆☆最盅,使用頻率:★★★☆☆】直接出處:裝飾模式梳理和學(xué)習(xí):https://github.com/...
    BruceOuyang閱讀 716評論 2 2
  • (轉(zhuǎn)載)原文地址 在閻宏博士的《JAVA與模式》一書中開頭是這樣描述裝飾(Decorator)模式的: 裝飾模式又...
    zjk_00閱讀 630評論 0 2
  • 在閻宏博士的《JAVA與模式》一書中開頭是這樣描述裝飾(Decorator)模式的: 裝飾模式又名包裝(Wrapp...
    聶叼叼閱讀 347評論 1 2
  • 1 概述 在一個項目中涡贱,你會有非常多的因素考慮不到,特別是業(yè)務(wù)的變更惹想,不時的冒出一個需求是很正常的情況问词。有三個繼承...
    今晚打肉山閱讀 295評論 0 0
  • 一、模式動機(jī) 一般有兩種方式可以實現(xiàn)給一個類或?qū)ο笤黾有袨椋?繼承機(jī)制嘀粱,使用繼承機(jī)制是給現(xiàn)有類添加功能的一種有效途...
    端木軒閱讀 512評論 0 0