装饰器模式(Decorator Pattern)
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地给对象添加新的行为,而不改变其结构。以下是一个用 Java 实现的装饰器模式示例:
示例:咖啡店
假设你有一个咖啡店,咖啡有不同的类型(如 Espresso、Latte),并且可以添加不同的调料(如牛奶、糖、巧克力)。你希望能够动态地给咖啡添加这些调料。
代码实现
- 创建
Beverage
接口:这是所有饮料类的公共接口。
public interface Beverage {
String getDescription();
double cost();
}
- 创建具体的饮料类:如 Espresso 和 Latte。
public class Espresso implements Beverage {
@Override
public String getDescription() {
return "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
public class Latte implements Beverage {
@Override
public String getDescription() {
return "Latte";
}
@Override
public double cost() {
return 2.99;
}
}
- 创建装饰器抽象类:所有的调料装饰器都需要继承这个类。
public abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
public CondimentDecorator(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription();
}
@Override
public double cost() {
return beverage.cost();
}
}
- 创建具体的装饰器类:如牛奶和巧克力。
public class Milk extends CondimentDecorator {
public Milk(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Milk";
}
@Override
public double cost() {
return beverage.cost() + 0.5;
}
}
public class Chocolate extends CondimentDecorator {
public Chocolate(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Chocolate";
}
@Override
public double cost() {
return beverage.cost() + 0.7;
}
}
- 客户端代码:使用装饰器模式来创建饮料,并添加调料。
public class CoffeeShop {
public static void main(String[] args) {
// 创建一个Espresso,不加任何调料
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());
// 创建一个加牛奶的Latte
Beverage latteWithMilk = new Milk(new Latte());
System.out.println(latteWithMilk.getDescription() + " $" + latteWithMilk.cost());
// 创建一个加牛奶和巧克力的Espresso
Beverage espressoWithMilkAndChocolate = new Chocolate(new Milk(new Espresso()));
System.out.println(espressoWithMilkAndChocolate.getDescription() + " $" + espressoWithMilkAndChocolate.cost());
}
}
输出结果
Espresso $1.99
Latte, Milk $3.49
Espresso, Milk, Chocolate $3.19
这个例子展示了如何使用装饰器模式来动态地给对象添加功能。在这个例子中,每个调料(如牛奶和巧克力)都作为一个装饰器,通过组合的方式与基本饮料对象(如 Espresso 和 Latte)组合在一起,从而实现了功能的扩展。