在Java中,装饰器模式允许我们动态地给对象添加新的行为或责任,而无需修改原有类。以下是一个简单的装饰器模式示例,我们将模拟一个咖啡销售系统,其中基础饮料类(Component)是Coffee,装饰器类(Decorator)用来添加额外的调料。
首先,定义抽象组件——基础咖啡接口:
// 抽象组件(Component)
public interface Coffee {double getCost(); // 获取咖啡价格String getDescription(); // 获取咖啡描述
}// 具体组件(ConcreteComponent)
public class SimpleCoffee implements Coffee {@Overridepublic double getCost() {return 1.0; // 基础咖啡的价格}@Overridepublic String getDescription() {return "Simple Coffee"; // 基础咖啡的描述}
}
接下来,创建装饰器接口:
// 装饰器接口(Decorator)
public abstract class CoffeeDecorator implements Coffee {protected Coffee coffee; // 维持对组件对象的引用public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic double getCost() {return coffee.getCost(); // 默认调用原始咖啡的价格}@Overridepublic String getDescription() {return coffee.getDescription(); // 默认调用原始咖啡的描述}
}
然后,我们创建几个具体的装饰器类,它们会附加额外的功能(比如添加糖、奶或者巧克力):
// 具体装饰器 - 添加糖
public class SugarDecorator extends CoffeeDecorator {private static final double SUGAR_COST = 0.25;public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + SUGAR_COST; // 在原始咖啡价格基础上增加糖的成本}@Overridepublic String getDescription() {return coffee.getDescription() + ", With Sugar"; // 更新描述信息}
}// 具体装饰器 - 添加牛奶
public class MilkDecorator extends CoffeeDecorator {private static final double MILK_COST = 0.5;public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + MILK_COST; // 在原始咖啡价格基础上增加牛奶的成本}@Overridepublic String getDescription() {return coffee.getDescription() + ", With Milk"; // 更新描述信息}
}// 可以继续定义其他装饰器,如ChocolateDecorator等...
最后,在客户端代码中,我们可以动态地构建不同口味的咖啡:
public class CoffeeShop {public static void main(String[] args) {Coffee simpleCoffee = new SimpleCoffee();System.out.println(simpleCoffee.getDescription() + " costs: " + simpleCoffee.getCost());Coffee coffeeWithSugar = new SugarDecorator(simpleCoffee);System.out.println(coffeeWithSugar.getDescription() + " costs: " + coffeeWithSugar.getCost());Coffee coffeeWithMilkAndSugar = new MilkDecorator(coffeeWithSugar);System.out.println(coffeeWithMilkAndSugar.getDescription() + " costs: " + coffeeWithMilkAndSugar.getCost());}
}
运行上述代码后,将会输出每种咖啡的描述和对应的价格,展示了如何通过装饰器模式动态地添加不同的调料并计算总成本。