什么是装饰器模式?
装饰器模式是一种结构型设计模式,它允许在不修改原有类的情况下,动态地为对象添加额外的职责和行为。这种模式提供了一种灵活的方式来扩展对象的功能,同时避免了通过继承导致的类爆炸问题。
装饰器模式的核心思想
装饰器模式的主要目标是:
- 动态地为对象添加新的功能
- 提供比继承更加灵活的扩展方式
- 遵循开闭原则(对扩展开放,对修改关闭)
UML类图
类图解析:
Component
是一个接口,定义了operation
方法。ConcreteComponent
是实现了Component
接口的具体类,包含基本操作。Decorator
是一个抽象类,实现了Component
接口,并持有一个Component
的引用。ConcreteDecoratorA
和ConcreteDecoratorB
是具体的装饰器类,继承自Decorator
,实现了额外功能的添加。
使用:
ConcreteComponent
作为核心对象,实现基本操作。- 通过
ConcreteDecoratorA
和ConcreteDecoratorB
,动态地为ConcreteComponent
添加新功能。
代码实现示例
1. 定义基础接口
// 咖啡接口
public interface Coffee {double getCost();String getDescription();
}
2. 创建基础实现类
// 基础咖啡实现
public class SimpleCoffee implements Coffee {@Overridepublic double getCost() {return 10.0;}@Overridepublic String getDescription() {return "简单咖啡";}
}
3. 创建抽象装饰器
// 抽象装饰器
public abstract class CoffeeDecorator implements Coffee {protected Coffee decoratedCoffee;public CoffeeDecorator(Coffee coffee) {this.decoratedCoffee = coffee;}@Overridepublic double getCost() {return decoratedCoffee.getCost();}@Overridepublic String getDescription() {return decoratedCoffee.getDescription();}
}
4. 创建具体装饰器
// 牛奶装饰器
public class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + 3.0;}@Overridepublic String getDescription() {return super.getDescription() + ", 加牛奶";}
}// 糖装饰器
public class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + 2.0;}@Overridepublic String getDescription() {return super.getDescription() + ", 加糖";}
}
5. 客户端使用示例
public class DecoratorDemo {public static void main(String[] args) {// 基础咖啡Coffee simpleCoffee = new SimpleCoffee();System.out.println("基础咖啡:" + simpleCoffee.getDescription());System.out.println("价格:" + simpleCoffee.getCost());// 加牛奶的咖啡Coffee milkCoffee = new MilkDecorator(simpleCoffee);System.out.println("加牛奶的咖啡:" + milkCoffee.getDescription());System.out.println("价格:" + milkCoffee.getCost());// 加糖和牛奶的咖啡Coffee sugarMilkCoffee = new SugarDecorator(new MilkDecorator(simpleCoffee));System.out.println("加糖和牛奶的咖啡:" + sugarMilkCoffee.getDescription());System.out.println("价格:" + sugarMilkCoffee.getCost());}
}
装饰器模式的优点
- 灵活性:可以在运行时动态添加职责
- 避免继承:提供了比继承更加灵活的扩展方式
- 单一职责:每个装饰器只负责一个特定的功能
- 易于扩展:添加新的装饰器不会影响现有代码
使用场景
装饰器模式适用于以下场景:
- 需要动态添加对象功能
- 不希望通过继承增加子类数量
- 需要为对象添加可选的行为
注意事项
- 装饰器模式会增加系统的复杂性
- 多层装饰可能会导致代码难以理解
- 尽量保持装饰器的轻量级和单一职责
结论
装饰器模式为我们提供了一种灵活、优雅的方式来扩展对象功能。通过使用装饰器,我们可以在不修改原有类的情况下,动态地为对象添加新的行为和职责。