背景
假设你有一个咖啡店,你的基本咖啡是黑咖啡。然而,你希望能够为客户提供添加额外配料(如牛奶、糖、巧克力等)的选项,而不需要为每种配料创建一个新的咖啡类。
这时,你可以使用装饰器模式来实现。
概述
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你在不改变现有对象结构的情况下,动态地将行为添加到对象中。通过将对象包装在具有相同父类或实现相同接口的装饰器类中,可以逐层地为对象添加功能。
代码示例
定义一个基本的咖啡接口 Coffee
:
public interface Coffee {
String getDescription();
double getCost();
}
创建一个具体的黑咖啡类 BlackCoffee
实现 Coffee
接口:
public class BlackCoffee implements Coffee {
@Override
public String getDescription() {
return "Black Coffee";
}
@Override
public double getCost() {
return 2.0;
}
}
定义一个装饰器接口 CoffeeDecorator
,表示咖啡的配料:
public interface CoffeeDecorator extends Coffee {
}
创建具体的装饰器类来实现 CoffeeDecorator
接口,例如牛奶装饰器类 MilkDecorator
:
public class MilkDecorator implements CoffeeDecorator {
private Coffee coffee;
public MilkDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription() + ", Milk";
}
@Override
public double getCost() {
return coffee.getCost() + 1.0;
}
}
同样,可以创建其他的装饰器类,例如糖装饰器类 SugarDecorator
:
public class SugarDecorator implements CoffeeDecorator {
private Coffee coffee;
public SugarDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription() + ", Sugar";
}
@Override
public double getCost() {
return coffee.getCost() + 0.5;
}
}
在客户端代码中使用装饰器模式来创建不同的咖啡对象:
public class Main {
public static void main(String[] args) {
// 创建一个黑咖啡对象
Coffee blackCoffee = new BlackCoffee();
System.out.println(blackCoffee.getDescription() + " - $" + blackCoffee.getCost());
// 创建一个加了牛奶的咖啡对象
Coffee milkCoffee = new MilkDecorator(blackCoffee);
System.out.println(milkCoffee.getDescription() + " - $" + milkCoffee.getCost());
// 创建一个既加了牛奶又加了糖的咖啡对象
Coffee milkSugarCoffee = new SugarDecorator(milkCoffee);
System.out.println(milkSugarCoffee.getDescription() + " - $" + milkSugarCoffee.getCost());
}
}
输出结果:
Black Coffee - $2.0
Black Coffee, Milk - $3.0
Black Coffee, Milk, Sugar - $3.5