设计模式-装饰器模式

作者持续关注WPS二次开发专题系列,持续为大家带来更多有价值的WPS开发技术细节,如果能够帮助到您,请帮忙来个一键三连,更多问题请联系我(QQ:250325397)

目录

定义

特点

使用场景

优缺点

(1) 优点

(2) 缺点

模式结构

具体实现

实际应用


定义

装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

特点

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

使用场景

    • 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
    • 当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现。
    • 当对象的功能要求可以动态地添加,也可以再动态地撤销时。

优缺点

(1) 优点
    • 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
    • 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
    • 装饰器模式完全遵守开闭原则
(2) 缺点
    • 装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

模式结构

装饰器模式主要包含以下角色。

    • 抽象构件(Shape)角色:定义一个抽象接口以规范准备接收附加责任的对象。
    • 具体构件(Circle、Rectangle)角色:实现抽象构件,通过装饰角色为其添加一些职责。
    • 抽象装饰(ShapeDecorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
    • 具体装饰(ResShapeDecorator、SolidShapeDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

具体实现

抽象类和具体实现类

/**
 * 形状,抽象类
 */
public abstract class Shape {
    /**
     * 边框颜色
     */
    protected int borderColor;

    /**
     * 边框样式,0:实线;1:虚线
     */
    protected int borderStyle;

    /**
     * 绘制
     */
    public abstract void draw();

    public int getBorderColor() {
        return borderColor;
    }

    public void setBorderColor(int borderColor) {
        this.borderColor = borderColor;
    }

    public int getBorderStyle() {
        return borderStyle;
    }

    public void setBorderStyle(int borderStyle) {
        this.borderStyle = borderStyle;
    }
}

/**
 * 圆形
 */
public class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("draw circle begin...");
    }
}

/**
 * 矩形
 */
public class Rectangle extends Shape {
    @Override
    public void draw() {
        System.out.println("draw rectangle begin...");
    }
}

抽象和具体装饰器

/**
 * 抽象装饰器类
 */
public abstract class ShapeDecorator extends Shape {
    protected Shape decoratedShape;

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

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

/**
 * 红色风格的装饰器实现类
 */
public class RedShapeDecorator extends ShapeDecorator {
    public RedShapeDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        fillRedColor();
        super.draw();
    }

    /**
     * 设置颜色
     */
    private void fillRedColor() {
        System.out.println("red shape: fill red color...");
        setBorderColor(Color.RED.getRGB());
    }
}

/**
 * 实线风格的形状装饰器实现类
 */
public class SolidShapeDecorator extends ShapeDecorator {
    public SolidShapeDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        setSolidBorder();
        super.draw();
    }

    private void setSolidBorder() {
        System.out.println("red shape: set solid border...");
        //0:实线
        setBorderStyle(0);
    }
}

具体使用

public class App {
    public static void main(String[] args) {
        //绘制红色风格的圆形
        Shape circle = new Circle();
        //红色风格装饰器
        ShapeDecorator redShapeDecorator = new RedShapeDecorator(circle);
        //实线风格装饰器
        SolidShapeDecorator solidShapeDecorator = new SolidShapeDecorator(redShapeDecorator);
        solidShapeDecorator.draw();


        //绘制实线风格的矩形
        Shape rectangle = new Rectangle();
        redShapeDecorator = new RedShapeDecorator(rectangle);
        //实线风格装饰器
        solidShapeDecorator = new SolidShapeDecorator(redShapeDecorator);
        solidShapeDecorator.draw();
    }
}

实际应用

Java I/O 标准库中InputStream 的子类 FilterInputStream,OutputStream 的子类 FilterOutputStream,Reader 的子类 BufferedReader 以及 FilterReader,还有 Writer 的子类 BufferedWriter、FilterWriter 以及 PrintWriter 等,它们都是抽象装饰类。

相关推荐

  1. 装饰设计模式

    2024-04-25 13:02:05       32 阅读
  2. 设计模式装饰模式

    2024-04-25 13:02:05       46 阅读
  3. 设计模式装饰模式

    2024-04-25 13:02:05       16 阅读
  4. 设计模式 —— 装饰模式

    2024-04-25 13:02:05       9 阅读

最近更新

  1. Node.js有什么优点

    2024-04-25 13:02:05       0 阅读
  2. Python爬虫-获取懂车帝“指定车型”的销量数据

    2024-04-25 13:02:05       0 阅读
  3. Django中模型的基于类的混入

    2024-04-25 13:02:05       1 阅读
  4. Impala写Parquet文件

    2024-04-25 13:02:05       1 阅读
  5. C# 反射

    2024-04-25 13:02:05       1 阅读
  6. 在程序中引用cuda.memory函数监控GPU内存

    2024-04-25 13:02:05       1 阅读

热门阅读

  1. go垃圾回收机制

    2024-04-25 13:02:05       11 阅读
  2. SqlServer 查询表、视图、存储过程被哪些引用

    2024-04-25 13:02:05       14 阅读
  3. 上位机工作感想-从C#到Qt的转变-2

    2024-04-25 13:02:05       12 阅读
  4. 算法训练营day22

    2024-04-25 13:02:05       11 阅读
  5. 【二叉树算法题记录】226. 翻转二叉树

    2024-04-25 13:02:05       12 阅读
  6. HOT100与剑指Offer

    2024-04-25 13:02:05       12 阅读
  7. 监督算法建模前数据质量检查

    2024-04-25 13:02:05       11 阅读