Java设计模式之装饰模式详解
一、装饰模式核心思想
核心目标:动态地为对象添加额外功能,通过组合替代继承,实现功能的灵活扩展。如同给礼物层层包装,每层包装都能增加新特性。
二、装饰模式类图(Mermaid)
三、代码实现示例
1. 咖啡加料场景
// 组件接口:饮品
interface Beverage {
String getDescription();
double cost();
}
// 具体组件:基础咖啡
class Espresso implements Beverage {
public String getDescription() { return "浓缩咖啡"; }
public double cost() { return 12.0; }
}
// 抽象装饰器
abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
public CondimentDecorator(Beverage beverage) {
this.beverage = beverage;
}
}
// 具体装饰器:牛奶
class Milk extends CondimentDecorator {
public Milk(Beverage beverage) { super(beverage); }
public String getDescription() {
return beverage.getDescription() + " + 牛奶";
}
public double cost() {
return beverage.cost() + 3.5;
}
}
// 具体装饰器:焦糖
class Caramel extends CondimentDecorator {
public Caramel(Beverage beverage) { super(beverage); }
public String getDescription() {
return beverage.getDescription() + " + 焦糖";
}
public double cost() {
return beverage.cost() + 2.0;
}
}
// 客户端调用
Beverage coffee = new Espresso();
coffee = new Milk(coffee);
coffee = new Caramel(coffee);
System.out.println(coffee.getDescription() + ",总价:" + coffee.cost());
四、模式优缺点分析
✅ 优势
- 灵活扩展:运行时动态添加功能
- 避免继承爆炸:N种基础组件×M种装饰 → N+M个类
- 符合开闭原则:新增装饰类无需修改现有代码
❌ 缺点
- 产生大量小类:可能增加系统复杂度
- 装饰顺序敏感:不同顺序导致不同结果
五、典型应用场景
- IO流处理:Java的
BufferedInputStream
装饰FileInputStream
- GUI组件:为窗口添加滚动条、边框等装饰
- Web过滤器链:Servlet Filter层层处理请求
- 日志增强:为方法调用添加性能监控日志
- 权限校验:动态添加访问控制层
六、Mermaid序列图(多层装饰流程)
七、装饰模式 vs 其他模式
对比模式 | 核心区别 |
---|---|
代理模式 | 控制访问,功能预定义 |
适配器模式 | 改变对象接口 |
组合模式 | 处理整体-部分关系 |
八、Java标准库应用案例
Java I/O 流体系
九、透明与半透明装饰模式
类型 | 特点 | 实现方式 |
---|---|---|
透明模式 | 完全保持组件接口 | 装饰器仅增强现有方法 |
半透明模式 | 装饰器添加新方法 | 客户端需知道具体装饰类型 |
半透明模式示例:
abstract class AdvancedDecorator extends Beverage {
public abstract void extraFeature();
}
class WhippedCream extends AdvancedDecorator {
public void extraFeature() {
System.out.println("添加奶油造型");
}
}
十、最佳实践建议
- 优先使用组合:装饰器持有组件对象而非继承
- 保持接口纯洁:尽量使用透明装饰模式
- 控制装饰层数:避免过度装饰导致性能下降
- 与工厂模式结合:通过工厂管理装饰过程
装饰不是继承的替代,而是补充
如果文章对你有帮助,帮忙点点关注吧,谢谢啦