Java设计模式 十 装饰模式 (Decorator Pattern)

装饰模式 (Decorator Pattern)

装饰模式 是一种结构型设计模式 ,它的作用是动态地为对象添加额外的职责,而不修改其代码结构。装饰模式通过创建装饰类,将核心功能与附加功能分离,使得代码更灵活,更具扩展性。


1. 装饰模式的组成

装饰模式包含以下角色:

  • Component(抽象组件): 定义对象的通用接口,可以动态地为该接口添加职责。
  • ConcreteComponent(具体组件): 组件的具体实现,是最基础的对象。
  • Decorator(装饰器): 持有一个 Component 的引用,并定义一个与 Component 一致的接口。
  • ConcreteDecorator(具体装饰器): 实现具体的装饰功能,同时调用组件的核心功能。

2. 装饰模式的优点

  1. 功能扩展灵活: 可以动态地为对象添加功能,而不需要修改原有类。
  2. 遵循开闭原则: 增加功能时,无需修改已有代码,只需增加新的装饰器类。
  3. 细粒度控制: 每个装饰器只负责一个特定的功能,职责单一。

3. 装饰模式的缺点

  1. 增加复杂性: 每个装饰器都是一个新的类,可能导致类数量增加。
  2. 调试困难: 如果多个装饰器嵌套使用,可能会导致调试和排错复杂化。

4. 装饰模式的实现

场景示例:给文本添加装饰功能

需求: 假设我们有一个文本处理组件,支持基本的文本输出功能。现在需要为它动态添加功能,比如加粗、斜体、添加颜色等。


1) 定义抽象组件

抽象组件定义通用接口,表示所有文本处理组件的公共行为。

java 复制代码
// 抽象组件
public interface Text {
    String render(); // 渲染文本
}

2) 实现具体组件

具体组件实现基本的文本渲染功能。

java 复制代码
// 具体组件
public class PlainText implements Text {
    private String content;

    public PlainText(String content) {
        this.content = content;
    }

    @Override
    public String render() {
        return content;
    }
}

3) 定义装饰器

装饰器类持有一个 Text 的引用,负责为组件动态添加功能。

java 复制代码
// 抽象装饰器
public abstract class TextDecorator implements Text {
    protected Text text;

    public TextDecorator(Text text) {
        this.text = text;
    }

    @Override
    public String render() {
        return text.render();
    }
}

4) 实现具体装饰器

具体装饰器负责添加不同的功能,例如加粗和斜体。

java 复制代码
// 加粗装饰器
public class BoldText extends TextDecorator {
    public BoldText(Text text) {
        super(text);
    }

    @Override
    public String render() {
        return "<b>" + super.render() + "</b>";
    }
}

// 斜体装饰器
public class ItalicText extends TextDecorator {
    public ItalicText(Text text) {
        super(text);
    }

    @Override
    public String render() {
        return "<i>" + super.render() + "</i>";
    }
}

// 颜色装饰器
public class ColoredText extends TextDecorator {
    private String color;

    public ColoredText(Text text, String color) {
        super(text);
        this.color = color;
    }

    @Override
    public String render() {
        return "<span style='color:" + color + "'>" + super.render() + "</span>";
    }
}

5) 客户端代码

客户端可以自由组合不同的装饰器来扩展功能。

java 复制代码
public class Client {
    public static void main(String[] args) {
        // 基础文本
        Text text = new PlainText("Hello, World!");

        // 添加加粗功能
        Text boldText = new BoldText(text);

        // 添加斜体功能
        Text italicText = new ItalicText(boldText);

        // 添加颜色功能
        Text coloredText = new ColoredText(italicText, "red");

        // 渲染最终文本
        System.out.println(coloredText.render());
    }
}

运行结果:
复制代码
<span style='color:red'><i><b>Hello, World!</b></i></span>

最终输出的文本是带有颜色、加粗和斜体的 HTML 格式。


5. 装饰模式的应用场景

  1. 动态扩展功能:

    需要为对象动态添加功能,并且可能在运行时组合多种功能。

  2. 代替继承:

    使用装饰模式可以避免通过继承实现功能扩展,减少类的数量。

  3. 需要根据不同需求组合功能:

    比如 GUI 系统中的组件,可能需要动态添加滚动条、边框、阴影等功能。


6. Java 中的典型应用

  1. java.io 包中的装饰器模式

    • InputStreamOutputStream 类的子类:

      • BufferedInputStream
      • DataInputStream
      • FilterInputStream
    • 通过装饰器动态扩展流的功能:

      java 复制代码
      InputStream input = new FileInputStream("file.txt");
      InputStream bufferedInput = new BufferedInputStream(input);
  2. Java Swing

    • Java Swing 的组件可以动态添加边框等效果:

      java 复制代码
      JTextField textField = new JTextField();
      textField.setBorder(BorderFactory.createLineBorder(Color.BLACK));

7. 装饰模式与其他模式的比较

模式 主要用途 与装饰模式的区别
代理模式 控制对象的访问 代理模式不改变对象的功能,装饰模式增加新功能。
适配器模式 接口不兼容的对象协同工作 适配器模式主要解决接口问题,装饰模式动态增强功能。
桥接模式 分离抽象和实现 桥接模式关注结构设计,装饰模式关注动态增强功能。

8. 总结

装饰模式是一种灵活、优雅的设计模式,它通过组合的方式动态为对象添加功能,而不修改原有代码。装饰模式遵循开闭原则,是功能扩展需求中的理想选择。

在实际开发中,装饰模式广泛应用于流处理、GUI 系统以及其他需要动态功能扩展的场景。它是一种高效且值得掌握的设计模式。

相关推荐
pnoker8 分钟前
IoT DC3 概念解读:把设备抽象成一套语义模板——位号、指令、事件与面向智能体的设备建模
java·人工智能·物联网·iot·dc3
my_realmy9 分钟前
Java SE 基础学习笔记(一):面向对象、继承多态、抽象接口与异常(JDK 8)
java·多线程·并发··生产者消费者模式
天远数科43 分钟前
风险治理实战:基于天远车信盟出险构建自动化理赔核保流水线
java·网络·人工智能·自动化
骇客野人1 小时前
SpringBoot电商系统用户注册、登录、留存及数据埋点设计与落地实施方案
java·spring boot·后端
qiuhaipeng11 小时前
Claude code 升级后上下文长度变短问题
java·前端·数据库
wxwx_bscxy3222 小时前
基于Python新冠疫情可视化分析系统的设计与实现
java·数据库·spring boot·python·微信小程序·sqlite
evans在进步3 小时前
Tomcat NIO 工作原理详解:从 Acceptor、Poller 到容器处理链
java·tomcat·nio
渡我白衣4 小时前
并查集:基础认识与模拟实现
android·java·javascript·数据结构·c++·算法·并查集
电商API_180079052475 小时前
电商商品价格监控工具淘宝京东商品价格抓取API项目实操分享
java·大数据·开发语言·前端·数据挖掘
zzzll11115 小时前
深度剖析:HashMap 并发死循环与 ConcurrentHashMap 两代演进全解
java·开发语言