本文目录导读:

装饰器模式核心思想
装饰器模式允许动态地给对象添加额外功能,比继承更灵活,核心是:
- 不修改原有类结构
- 通过组合方式扩展功能
- 支持多层装饰
基础案例:咖啡点单系统
抽象组件接口
// 咖啡组件接口
public interface Coffee {
String getDescription();
double cost();
}
具体组件(基础实现)
// 基础咖啡 - 美式咖啡
public class AmericanCoffee implements Coffee {
@Override
public String getDescription() {
return "美式咖啡";
}
@Override
public double cost() {
return 20.0;
}
}
// 基础咖啡 - 拿铁
public class Latte implements Coffee {
@Override
public String getDescription() {
return "拿铁";
}
@Override
public double cost() {
return 25.0;
}
}
抽象装饰器
// 装饰器抽象类,核心:持有Coffee引用
public abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
// 默认委托给被装饰对象
@Override
public String getDescription() {
return coffee.getDescription();
}
@Override
public double cost() {
return coffee.cost();
}
}
具体装饰器(功能扩展)
// 加奶装饰器
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + " + 牛奶";
}
@Override
public double cost() {
return coffee.cost() + 5.0; // 加奶额外5元
}
}
// 加糖装饰器
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + " + 糖";
}
@Override
public double cost() {
return coffee.cost() + 2.0; // 加糖额外2元
}
}
// 加奶油装饰器
public class WhipDecorator extends CoffeeDecorator {
public WhipDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + " + 奶油";
}
@Override
public double cost() {
return coffee.cost() + 8.0; // 加奶油额外8元
}
}
使用示例
基本使用
public class CoffeeShop {
public static void main(String[] args) {
// 基础美式咖啡
Coffee coffee = new AmericanCoffee();
System.out.println(coffee.getDescription() + ":¥" + coffee.cost());
// 输出:美式咖啡:¥20.0
// 美式 + 牛奶
Coffee milkCoffee = new MilkDecorator(new AmericanCoffee());
System.out.println(milkCoffee.getDescription() + ":¥" + milkCoffee.cost());
// 输出:美式咖啡 + 牛奶:¥25.0
// 美式 + 牛奶 + 糖
Coffee sweetMilkCoffee = new SugarDecorator(
new MilkDecorator(new AmericanCoffee())
);
System.out.println(sweetMilkCoffee.getDescription() + ":¥" + sweetMilkCoffee.cost());
// 输出:美式咖啡 + 牛奶 + 糖:¥27.0
// 拿铁 + 奶油 + 糖
Coffee latteWithWhipAndSugar = new SugarDecorator(
new WhipDecorator(new Latte())
);
System.out.println(latteWithWhipAndSugar.getDescription() + ":¥" + latteWithWhipAndSugar.cost());
// 输出:拿铁 + 奶油 + 糖:¥35.0
}
}
动态组合
// 可以根据用户选择动态组合
public Coffee createCustomCoffee(String base, List<String> addons) {
Coffee coffee;
// 选择基底
switch (base) {
case "美式":
coffee = new AmericanCoffee();
break;
case "拿铁":
coffee = new Latte();
break;
default:
throw new IllegalArgumentException("未知咖啡类型");
}
// 动态添加配料
for (String addon : addons) {
switch (addon) {
case "牛奶":
coffee = new MilkDecorator(coffee);
break;
case "糖":
coffee = new SugarDecorator(coffee);
break;
case "奶油":
coffee = new WhipDecorator(coffee);
break;
}
}
return coffee;
}
更复杂的功能拓展
添加新功能:杯子大小
// 杯子大小装饰器
public class SizeDecorator extends CoffeeDecorator {
private String size;
public SizeDecorator(Coffee coffee, String size) {
super(coffee);
this.size = size;
}
@Override
public String getDescription() {
return size + "杯 " + coffee.getDescription();
}
@Override
public double cost() {
double baseCost = coffee.cost();
switch (size) {
case "大":
return baseCost + 5.0;
case "中":
return baseCost + 3.0;
default: // 小
return baseCost;
}
}
}
// 使用
Coffee largeMilkCoffee = new SizeDecorator(
new MilkDecorator(new AmericanCoffee()), "大"
);
System.out.println(largeMilkCoffee.getDescription() + ":¥" + largeMilkCoffee.cost());
// 输出:大杯 美式咖啡 + 牛奶:¥30.0
添加新功能:温度控制
public class TemperatureDecorator extends CoffeeDecorator {
private String temperature;
public TemperatureDecorator(Coffee coffee, String temperature) {
super(coffee);
this.temperature = temperature;
}
@Override
public String getDescription() {
return coffee.getDescription() + "(" + temperature + ")";
}
@Override
public double cost() {
// 冰咖啡额外收费
if ("冰".equals(temperature)) {
return coffee.cost() + 2.0;
}
return coffee.cost();
}
}
// 多层装饰示例
Coffee customCoffee = new TemperatureDecorator(
new SizeDecorator(
new SugarDecorator(
new WhipDecorator(new Latte())
), "中"
), "冰"
);
System.out.println(customCoffee.getDescription() + ":¥" + customCoffee.cost());
// 输出:中杯 拿铁 + 奶油 + 糖(冰):¥40.0
进阶:使用接口+泛型
// 更通用的装饰器接口
public interface Decorator<T> {
T decorate(T target);
}
// 具体装饰器可以更灵活
public class LoggingDecorator<T> implements Decorator<T> {
@Override
public T decorate(T target) {
// 可以为任何对象添加日志功能
System.out.println("调用对象:" + target.getClass().getSimpleName());
return target;
}
}
实际应用场景
- Java I/O流:
BufferedInputStream装饰FileInputStream - Spring框架:
@Transactional、@Cacheable等注解 - Servlet Filter:多个Filter链式处理请求
- 日志框架:不同Appender、Layout的组合
注意事项
优点
- ✅ 比继承更灵活
- ✅ 遵循开闭原则
- ✅ 功能可以动态组合
- ✅ 避免类爆炸
缺点
- ❌ 会产生很多小类
- ❌ 多层装饰时调试复杂
- ❌ 装饰顺序可能影响结果
最佳实践
- 明确边界:装饰器应只添加功能,不改变核心逻辑
- 保持简单:避免超过3-4层装饰
- 工厂方法:结合工厂模式简化创建过程
- 文档清晰:记录装饰器的执行顺序
通过装饰器模式,您可以像搭积木一样灵活组合功能,既保持了代码的整洁,又提供了无限扩展的可能性。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播