设计模式-装饰器模式

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

目录

定义

特点

使用场景

优缺点

[(1) 优点](#(1) 优点)

[(2) 缺点](#(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 等,它们都是抽象装饰类。

相关推荐
皮皮林55110 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
卡尔特斯14 小时前
Android Kotlin 项目代理配置【详细步骤(可选)】
android·java·kotlin
白鲸开源14 小时前
Ubuntu 22 下 DolphinScheduler 3.x 伪集群部署实录
java·ubuntu·开源
ytadpole14 小时前
Java 25 新特性 更简洁、更高效、更现代
java·后端
纪莫15 小时前
A公司一面:类加载的过程是怎么样的? 双亲委派的优点和缺点? 产生fullGC的情况有哪些? spring的动态代理有哪些?区别是什么? 如何排查CPU使用率过高?
java·java面试⑧股
JavaGuide15 小时前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
用户37215742613515 小时前
Java 轻松批量替换 Word 文档文字内容
java
白鲸开源15 小时前
教你数分钟内创建并运行一个 DolphinScheduler Workflow!
java
晨米酱16 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
Java中文社群16 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试