1.装饰器模式介绍
装饰器模式是一种结构型设计模式,允许你动态地给对象添加行为,而无需修改其代码。它的核心思想是将对象放入一个“包装器”中,这个包装器提供了额外的功能,同时保持原有对象的接口不变。
想象一下,你有一个简单的咖啡,你想让它变得更特别。你可以给它加奶、加糖、加香草等等,但咖啡本身还是咖啡。这些额外的东西不会改变咖啡的本质,只是让它更丰富。
装饰器模式有四个角色:
- 抽象组件(Component):可以是一个接口或者抽象类,规定了被装饰对象的行为;
- 具体组件(ConcreteComponent):实现或继承Component的一个具体对象,也即被装饰对象;
- 抽象装饰器(Decorator):一般是抽象类, 继承或实现抽象组件Component;其内部必然有一个属性指向Component组件对象;通过其子类 ConcreteDecorator 扩展具体构件的功能。
- 具体装饰器(ConcreteDecorator):Decorator的具体实现类,理论上每个ConcreteDecorator 都扩展了 Component 对象的一种功能;
四个角色的关系:
2.代码演示
抽象组件(Component):咖啡接口定义了咖啡有“描述”和“价格”两个方法
// 基础接口
interface Coffee {
String getDescription();
double getCost();
}
具体组件(ConcreteComponent): 咖啡实现类,是需要被装饰的对象
// 具体的咖啡类
class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "Simple Coffee";
}
@Override
public double getCost() {
return 5.0;
}
}
抽象装饰器(Decorator):抽象类,实现咖啡接口,内部有一个属性指向Coffee对象
// 装饰器基类
abstract class CoffeeDecorator implements Coffee {
//内部必然有一个属性指向Component组件对象
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription();
}
@Override
public double getCost() {
return coffee.getCost();
}
}
具体装饰器(ConcreteDecorator):每个Coffee装饰器都扩展了Coffee对象的一种功能
// 具体的装饰器类
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + ", Milk";
}
@Override
public double getCost() {
return coffee.getCost() + 1.5;
}
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + ", Sugar";
}
@Override
public double getCost() {
return coffee.getCost() + 0.5;
}
}
使用装饰器:每个装饰器都可以单独或组合使用,给咖啡增加不同的特性。通过这种方式,原来的咖啡类保持不变,而我们可以灵活地为它添加新功能
// 使用装饰器模式
public class CoffeeShop {
public static void main(String[] args) {
//创建简单的咖啡类SimpleCoffee
Coffee coffee = new SimpleCoffee();
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
//通过装饰器MilkDecorator给咖啡加奶
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
//通过装饰器SugarDecorator给咖啡加糖
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
}
}