本文目录导读:

Java装饰器模式案例详解
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构,这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
核心角色
- Component(抽象组件):定义规范
- ConcreteComponent(具体组件):被装饰的原始对象
- Decorator(抽象装饰器):持有Component引用
- ConcreteDecorator(具体装饰器):添加额外功能
完整案例
抽象组件接口
// 咖啡接口(抽象组件)
public interface Coffee {
String getDescription();
double getCost();
}
具体组件
// 原味咖啡(具体组件)
public class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "原味咖啡";
}
@Override
public double getCost() {
return 10.0;
}
}
抽象装饰器
// 咖啡装饰器(抽象装饰器)
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription();
}
@Override
public double getCost() {
return decoratedCoffee.getCost();
}
}
具体装饰器
// 牛奶装饰器
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription() + " + 牛奶";
}
@Override
public double getCost() {
return super.getCost() + 3.0;
}
}
// 糖装饰器
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription() + " + 糖";
}
@Override
public double getCost() {
return super.getCost() + 2.0;
}
}
// 奶油装饰器
public class WhipDecorator extends CoffeeDecorator {
public WhipDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription() + " + 奶油";
}
@Override
public double getCost() {
return super.getCost() + 5.0;
}
}
客户端测试
public class DecoratorPatternDemo {
public static void main(String[] args) {
System.out.println("=== 装饰器模式案例:咖啡点单系统 ===\n");
// 基础咖啡
Coffee simpleCoffee = new SimpleCoffee();
System.out.println("基础款: " + simpleCoffee.getDescription()
+ " | 价格: ¥" + simpleCoffee.getCost());
// 加牛奶
Coffee milkCoffee = new MilkDecorator(simpleCoffee);
System.out.println("加牛奶: " + milkCoffee.getDescription()
+ " | 价格: ¥" + milkCoffee.getCost());
// 加牛奶和糖
Coffee milkSugarCoffee = new SugarDecorator(new MilkDecorator(simpleCoffee));
System.out.println("加牛奶+糖: " + milkSugarCoffee.getDescription()
+ " | 价格: ¥" + milkSugarCoffee.getCost());
// 加所有配料
Coffee fullCoffee = new WhipDecorator(
new SugarDecorator(
new MilkDecorator(simpleCoffee)));
System.out.println("豪华版: " + fullCoffee.getDescription()
+ " | 价格: ¥" + fullCoffee.getCost());
// Java I/O 中的装饰器模式对比
System.out.println("\n=== Java I/O 中的装饰器模式 ===");
System.out.println("BufferedReader reader = new BufferedReader(");
System.out.println(" new InputStreamReader(");
System.out.println(" new FileInputStream(\"file.txt\")));");
}
}
运行结果
=== 装饰器模式案例:咖啡点单系统 ===
基础款: 原味咖啡 | 价格: ¥10.0
加牛奶: 原味咖啡 + 牛奶 | 价格: ¥13.0
加牛奶+糖: 原味咖啡 + 牛奶 + 糖 | 价格: ¥15.0
豪华版: 原味咖啡 + 牛奶 + 糖 + 奶油 | 价格: ¥20.0
=== Java I/O 中的装饰器模式 ===
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream("file.txt")));
JDK中的装饰器模式应用
Java标准库中大量使用了装饰器模式,最典型的是I/O流:
// 文件读取的装饰链
FileInputStream fis = new FileInputStream("test.txt"); // 基础组件
InputStreamReader isr = new InputStreamReader(fis); // 装饰器
BufferedReader br = new BufferedReader(isr); // 装饰器
// GUI组件
Component component = new JButton("OK");
component = new BorderDecorator(component);
component = new ScrollBarDecorator(component);
装饰器模式 vs 继承
| 特性 | 装饰器模式 | 继承 |
|---|---|---|
| 扩展方式 | 组合方式 | 静态继承 |
| 灵活性 | 运行时动态添加 | 编译时确定 |
| 类爆炸 | 避免 | 容易产生大量子类 |
| 功能组合 | 灵活组合 | 需要预定义 |
最佳实践建议
- 透明性:装饰器应该保持与组件相同的接口
- 多层装饰:可以无限嵌套装饰器
- 轻量级:避免装饰器过于复杂
- 性能考虑:过多层装饰可能影响性能
装饰器模式是Java中非常实用的设计模式,特别适合需要动态扩展功能的场景,如日志记录、权限验证、数据压缩等功能增强。