Java装饰模式
外观
概述[编辑 | 编辑源代码]
装饰模式(Decorator Pattern)是一种结构型设计模式,允许通过将对象放入包含行为的特殊封装类中来动态地扩展对象的功能。该模式提供了一种灵活的替代方案,比继承更易于维护和扩展,遵循开闭原则(对扩展开放,对修改封闭)。
核心思想[编辑 | 编辑源代码]
- 动态地为对象添加额外职责,而无需修改其原始类。
- 通过组合而非继承实现功能扩展。
- 装饰器类与被装饰对象实现同一接口,形成透明嵌套结构。
结构[编辑 | 编辑源代码]
- Component:定义对象的接口,可以是抽象类或接口。
- ConcreteComponent:实现基础功能的具体类。
- Decorator:持有对Component的引用,并实现其接口。
- ConcreteDecorator:具体装饰器,添加新功能或状态。
代码示例[编辑 | 编辑源代码]
以下是一个模拟咖啡订单系统的示例,展示如何通过装饰模式动态添加配料(如牛奶、糖)的价格和描述。
基础组件[编辑 | 编辑源代码]
// 抽象组件
public interface Coffee {
double getCost();
String getDescription();
}
// 具体组件
public class SimpleCoffee implements Coffee {
@Override
public double getCost() {
return 2.0; // 基础咖啡价格
}
@Override
public String getDescription() {
return "Simple coffee";
}
}
装饰器实现[编辑 | 编辑源代码]
// 抽象装饰器
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
@Override
public double getCost() {
return decoratedCoffee.getCost();
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription();
}
}
// 具体装饰器:牛奶
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 0.5; // 增加牛奶价格
}
@Override
public String getDescription() {
return super.getDescription() + ", with milk";
}
}
// 具体装饰器:糖
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 0.2; // 增加糖价格
}
@Override
public String getDescription() {
return super.getDescription() + ", with sugar";
}
}
使用示例[编辑 | 编辑源代码]
public class Main {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println("Cost: " + coffee.getCost() + "; Description: " + coffee.getDescription());
coffee = new MilkDecorator(coffee);
System.out.println("Cost: " + coffee.getCost() + "; Description: " + coffee.getDescription());
coffee = new SugarDecorator(coffee);
System.out.println("Cost: " + coffee.getCost() + "; Description: " + coffee.getDescription());
}
}
输出:
Cost: 2.0; Description: Simple coffee Cost: 2.5; Description: Simple coffee, with milk Cost: 2.7; Description: Simple coffee, with milk, with sugar
实际应用场景[编辑 | 编辑源代码]
- Java I/O流:
BufferedReader
、InputStreamReader
等通过嵌套装饰器增强功能。 - GUI组件:为窗口添加滚动条、边框等动态效果。
- Web开发:中间件链(如权限检查、日志记录)的装饰器实现。
优缺点[编辑 | 编辑源代码]
优点 | 缺点 |
---|---|
避免继承导致的类爆炸 | 增加代码复杂度(多层嵌套) |
动态扩展对象功能 | 调试困难(需逐层检查装饰器) |
符合单一职责原则(每个装饰器独立) |
进阶主题[编辑 | 编辑源代码]
- 与代理模式的区别:装饰器关注增强功能,代理控制访问。
- 多层装饰器的性能影响(如Java I/O的嵌套开销)。