跳到主要内容

装饰器模式

介绍

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有对象添加新的功能,同时又不改变其结构。装饰器模式通过创建一个包装对象来包裹真实对象,并在保持真实对象接口不变的前提下,提供额外的功能。

原理

装饰器模式的核心原理包括:

  1. 抽象组件:定义被装饰对象的接口
  2. 具体组件:实现抽象组件接口的基本功能
  3. 抽象装饰器:继承抽象组件,并包含一个抽象组件的引用
  4. 具体装饰器:实现抽象装饰器的方法,添加额外功能

图示

+----------------+        +----------------+
| Component | | Client |
+----------------+ +----------------+
| + operation() |<-------| + main() |
+-------^--------+ +----------------+
|
+-------+--------+ +----------------+
| ConcreteComponent| | Decorator |
+----------------+ +----------------+
| + operation() | | - component |
+----------------+ | + operation() |
+-------^--------+
|
+---------+----------+
| |
+----------------+ +----------------+
| ConcreteDecoratorA | | ConcreteDecoratorB |
+----------------+ +----------------+
| - component | | - component |
| + operation() | | + operation() |
| + addedFeatureA()| | + addedFeatureB()|
+----------------+ +----------------+

代码示例

抽象组件

public interface Component {
void operation();
}

具体组件

public class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("基础功能");
}
}

抽象装饰器

public abstract class Decorator implements Component {
protected Component component;

public Decorator(Component component) {
this.component = component;
}

@Override
public void operation() {
component.operation();
}
}

具体装饰器

public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}

@Override
public void operation() {
super.operation();
addedFeatureA();
}

public void addedFeatureA() {
System.out.println("添加功能A");
}
}

public class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}

@Override
public void operation() {
super.operation();
addedFeatureB();
}

public void addedFeatureB() {
System.out.println("添加功能B");
}
}

客户端代码

public class Client {
public static void main(String[] args) {
Component component = new ConcreteComponent();
System.out.println("原始组件:");
component.operation();

Component decoratorA = new ConcreteDecoratorA(component);
System.out.println("装饰器A:");
decoratorA.operation();

Component decoratorB = new ConcreteDecoratorB(decoratorA);
System.out.println("装饰器B + 装饰器A:");
decoratorB.operation();
}
}

解决方案

应用场景

  1. 动态添加功能:需要在运行时动态地为对象添加功能,而不影响其他对象
  2. 功能组合:需要组合多个功能,而不使用继承导致类爆炸
  3. 替代继承:当继承会导致类数量急剧增加时,使用装饰器模式更合适
  4. 遵循开闭原则:对扩展开放,对修改关闭

最佳实践

  1. 保持接口一致:装饰器和被装饰对象必须实现相同的接口
  2. 避免过度装饰:不要为了添加过多的功能而创建复杂的装饰链
  3. 简化具体装饰器:每个具体装饰器只添加一个功能
  4. 考虑使用工厂模式:结合工厂模式创建装饰后的对象

优缺点

优点

  • 动态添加功能,无需修改原有代码
  • 避免使用继承导致的类爆炸
  • 符合开闭原则
  • 可以灵活组合多种功能

缺点

  • 增加代码复杂度
  • 可能导致出现大量小装饰器类
  • 调试难度增加

工具推荐

  1. Java I/O库:大量使用装饰器模式,如BufferedReader、DataInputStream等
  2. Guava:提供装饰器工具类,如Maps.synchronizedMap()
  3. Spring Framework:提供装饰器实现,如TransactionAwareProxyFactoryBean
  4. Apache Commons IO:提供多种I/O装饰器