Java编程之装饰器模式

发布于:2025-06-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

概述

装饰器模式是结构型模式,其核心意图是:在不修改原始对象的基础上,动态地添加新行为,而且仅影响被装饰的对象,不影响同类其他实例 。这种模式避免了继承导致的类爆炸问题,同时符合开闭原则(对扩展开放,对修改关闭)。

模式结构

在这里插入图片描述

整体结构分为四大角色:

角色 说明
Component 核心接口/抽象类,定义可装饰交互 operation()
ConcreteComponent 具体组件,提供默认行为实现
Decorator 抽象装饰器,实现 Component 接口,包含对 Component 的引用,并在内部调用其方法
ConcreteDecorator 具体装饰器,继承 Decorator,实现前置或后置增强逻辑

UML 图示可见上方图片中 Component、ConcreteComponent、Decorator、ConcreteDecorator 的层次结构。

代码样例

// Component 接口
public interface Coffee {
    String getDescription();
    double getCost();
}

// ConcreteComponent
public class PlainCoffee implements Coffee {
    @Override public String getDescription() { return "Plain Coffee"; }
    @Override public double getCost() { return 2.0; }
}

// 抽象装饰器
public abstract class CoffeeDecorator implements Coffee {
    protected final Coffee decorated;
    public CoffeeDecorator(Coffee decorated) { this.decorated = decorated; }
    @Override public String getDescription() { return decorated.getDescription(); }
    @Override public double getCost() { return decorated.getCost(); }
}

// 多个具体装饰器
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee c) { super(c); }
    @Override public String getDescription() { return super.getDescription() + ", Milk"; }
    @Override public double getCost() { return super.getCost() + 0.5; }
}

public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee c) { super(c); }
    @Override public String getDescription() { return super.getDescription() + ", Sugar"; }
    @Override public double getCost() { return super.getCost() + 0.2; }
}

客户端构造示例

Coffee coffee = new SugarDecorator(new MilkDecorator(new PlainCoffee()));
System.out.println(coffee.getDescription()); // Plain Coffee, Milk, Sugar
System.out.println(coffee.getCost());        // 2.7

详细示例说明请参见 GeeksforGeeks 和 DigitalOcean 教程 ([geeksforgeeks.org][3])。

调用说明

  1. 客户端通过 new 创建基础对象(ConcreteComponent)。
  2. 可链式包装多个 Decorator。
  3. 每次调用 operation() (getDescription() and getCost()),都会调用当前装饰器的方法,先执行增强逻辑,再委派给被装饰对象,形成调用栈。

流程例如:
ConcreteDecorator2.getDescription()
增强逻辑 →
ConcreteDecorator1.getDescription()
增强 →
ConcreteComponent.getDescription()


ConcreteDecorator2.getCost()
增强逻辑 →
ConcreteDecorator1.getCost()
增强 →
ConcreteComponent.getCost()

应用场景

  • 1.Java I/O流体系
    通过装饰器模式实现流的缓冲、数据转换等功能。
    InputStream为抽象组件,FileInputStream为具体组件。
    BufferedInputStream、DataInputStream等作为装饰器,逐层扩展功能。
  • 2.GUI组件增强
    为窗口动态添加滚动条、边框等装饰,而无需修改原有组件类。
    如Swing中的JScrollPane装饰JPanel,动态添加滚动条功能。
  • 3.Web请求处理
    通过装饰器实现日志记录、权限校验等横向功能扩展。
  • 4.动态功能扩展
    如咖啡订单系统中动态添加配料,无需修改原有类。

优势与适用性分析

优势

  • 增强可组合性:行为可在运行时任意组合;
  • 遵循开闭原则:无需修改原始代码,易扩展;
  • 结构清晰,职责单一,每个装饰器聚焦一种功能。

缺点

  • 装饰链深了可能难以理解调试;
  • 对性能有轻微影响(多层对象调用开销);
  • 过度使用可能让系统变得复杂。

总结

装饰器模式通过将功能封装到多个小 decorator 中并按需动态组合,使得行为扩展既灵活又安全,是结构型设计的重要工具,适合于功能模块多变、扩展性要求高的场景,你学到了么?


网站公告

今日签到

点亮在社区的每一天
去签到