Skip to content

装饰器模式

字数: 0 字 时长: 0 分钟

简介

装饰模式(Decorator Pattern)核心思想是:动态地给对象添加额外的功能,而不会影响到其他对象。即不改变原始对象的基础结构,通过外层的装饰者给它加新能力。

UML 类图

decorator.webp

  • 组件接口(Component):定义对象的接口,所有的具体组件和装饰器都实现这个接口
  • 具体组件(ConcreteComponent):原始对象
  • 抽象装饰器(Decorator):实现组件接口,内部持有一个组件对象(被装饰的原始对象)
  • 具体装饰器(ConcreteDecorator):继承抽象装饰器,负责给组件对象添加新的功能

实现示例

实现一个最基础的显示文字内容的文本组件,通过装饰器添加加粗颜色等增强功能。

java
// 1. 组件接口,要去所有的文本类组件都要实现 render()
interface TextComponent {
    String render();
}

// 2. 原始组件(只具有最基本的显示文字内容功能)
class BasicText implements TextComponent {
    private String content;
    public BasicText(String content) {
        this.content = content;
    }
    @Override
    public String render() {
        return content;
    }
}

// 3. 抽象装饰器
abstract class TextDecorator implements TextComponent {
    protected TextComponent component;
    public TextDecorator(TextComponent component) {
        this.component = component;
    }
}

// 4. 第一个具体装饰器 (文字加粗)
class BlodDecorator extends TextDecorator {
    public BlodDecorator(TextComponent component) {
        super(component);
    }
    @Override
    public String render() {
        return "<b>" + component.render() + "</b>";
    }
}

// 5. 第二个具体装饰器 (文字颜色)
class ColorDecorator extends TextDecorator {
    private String color;
    public ColorDecorator(TextComponent component, String color) {
        super(component);
        this.color = color;
    }
    @Override
    public String render() {
        return "<span style='color'" + color + ">" + component.render() + "</span>";
    }
}

// 6. 调用示例
public static void main(String[] args) {
    TextComponent text = new BasicText("Hello");
    // 字体加粗
    text = new BoldDecorator(text);
    // 字体颜色
    text = new ColorDecorator(text, "red");
}

JDK I/O 流装饰模式应用

JDK 的 I/O 是装饰模式的典型应用

java
// Java I/O 是装饰器模式的经典应用

// 1. 基础文件读取
InputStream fileStream = new FileInputStream("data.txt");

// 2. 添加缓冲功能(第一层装饰)
BufferedInputStream bufferedStream =
        new BufferedInputStream(fileStream);

// 3. 添加解压功能(第二层装饰)
GZIPInputStream gzipStream =
        new GZIPInputStream(bufferedStream);

// 4. 添加对象反序列化功能(第三层装饰)
ObjectInputStream objectStream =
        new ObjectInputStream(gzipStream);

// 读取对象
MyObject obj = (MyObject) objectStream.readObject();