装饰器模式
介绍
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有对象添加新的功能,同时又不改变其结构。装饰器模式通过创建一个包装对象来包裹真实对象,并在保持真实对象接口不变的前提下,提供额外的功能。
原理
装饰器模式的核心原理包括:
- 抽象组件:定义被装饰对象的接口
- 具体组件:实现抽象组件接口的基本功能
- 抽象装饰器:继承抽象组件,并包含一个抽象组件的引用
- 具体装饰器:实现抽象装饰器的方法,添加额外功能
图示
+----------------+ +----------------+
| 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();
}
}
解决方案
应用场景
- 动态添加功能:需要在运行时动态地为对象添加功能,而不影响其他对象
- 功能组合:需要组合多个功能,而不使用继承导致类爆炸
- 替代继承:当继承会导致类数量急剧增加时,使用装饰器模式更合适
- 遵循开闭原则:对扩展开放,对修改关闭
最佳实践
- 保持接口一致:装饰器和被装饰对象必须实现相同的接口
- 避免过度装饰:不要为了添加过多的功能而创建复杂的装饰链
- 简化具体装饰器:每个具体装饰器只添加一个功能
- 考虑使用工厂模式:结合工厂模式创建装饰后的对象
优缺点
优点:
- 动态添加功能,无需修改原有代码
- 避免使用继承导致的类爆炸
- 符合开闭原则
- 可以灵活组合多种功能
缺点:
- 增加代码复杂度
- 可能导致出现大量小装饰器类
- 调试难度增加
工具推荐
- Java I/O库:大量使用装饰器模式,如BufferedReader、DataInputStream等
- Guava:提供装饰器工具类,如Maps.synchronizedMap()
- Spring Framework:提供装饰器实现,如TransactionAwareProxyFactoryBean
- Apache Commons IO:提供多种I/O装饰器