裝飾模式

描述

????裝飾模式(Decorator Pattern)又名包裝(Wrapper)模式。裝飾模式以對客戶端透明的方式擴展對象的功能,是繼承關系的一個替代方案。可以在不改變現(xiàn)有對象的結構的情況下,動態(tài)地擴展其功能。

簡介

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


裝飾模式類圖

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


只有一個ConcreteComponent類

????如果只有一個ConcreteDecorator類,那么就沒有必要建立一個單獨的Decorator類,而可以把Decorator和ConcreteDecorator的責任合并成一個類。甚至在只有兩個ConcreteDecorator類的情況下,都可以這樣做。
只有一個ConcreteDecorator類

角色

  • 抽象構件(Component)角色:給出一個抽象接口,以規(guī)范準備接收附加責任的對象。
  • 具體構件(ConcreteComponent)角色:定義一個將要接收附加責任的類。
  • 裝飾(Decorator)角色:持有一個構件(Component)對象的實例,并定義一個與抽象構件接口一致的接口。
  • 具體裝飾(ConcreteDecorator)角色:負責給構件對象“貼上”附加的責任。

優(yōu)缺點

優(yōu)點

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

缺點

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

使用場景

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

示例

/**
* 抽象構件(Component)角色
*/
public interface Shape {
    void draw();
}
/**
* 具體構件(ConcreteComponent)角色
*/
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape: Circle");
    }
}
/**
* 具體構件(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();
    }
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 【學習難度:★★★☆☆,使用頻率:★★★☆☆】直接出處:裝飾模式梳理和學習:https://github.com/...
    BruceOuyang閱讀 838評論 2 2
  • (轉載)原文地址 在閻宏博士的《JAVA與模式》一書中開頭是這樣描述裝飾(Decorator)模式的: 裝飾模式又...
    zjk_00閱讀 682評論 0 2
  • 在閻宏博士的《JAVA與模式》一書中開頭是這樣描述裝飾(Decorator)模式的: 裝飾模式又名包裝(Wrapp...
    聶叼叼閱讀 373評論 1 2
  • 1 概述 在一個項目中,你會有非常多的因素考慮不到,特別是業(yè)務的變更,不時的冒出一個需求是很正常的情況。有三個繼承...
    今晚打肉山閱讀 368評論 0 0
  • 一、模式動機 一般有兩種方式可以實現(xiàn)給一個類或對象增加行為: 繼承機制,使用繼承機制是給現(xiàn)有類添加功能的一種有效途...
    端木軒閱讀 569評論 0 0

友情鏈接更多精彩內(nèi)容