装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许动态地向一个现有的对象添加新的功能,同时不改变其结构。这种模式通过创建一个装饰类来包装原有的类,提供额外的行为。
下面是一个使用 Java 实现装饰者模式的实践案例:
场景描述
假设我们正在开发一个咖啡馆应用程序,需要能够计算订单中各种类型咖啡的成本。基本咖啡可以添加多种调料(如摩卡、奶泡、豆浆等),每种调料都会增加咖啡的成本。
步骤1:定义组件接口
1// 咖啡接口,作为所有咖啡和调料的基类
2public interface Coffee {
3 String getDescription();
4 double getCost();
5}
步骤2:实现具体组件
1// 简单咖啡类,实现咖啡接口
2public class SimpleCoffee implements Coffee {
3 @Override
4 public String getDescription() {
5 return "Simple Coffee";
6 }
7
8 @Override
9 public double getCost() {
10 return 10; // 基础价格
11 }
12}
步骤3:创建装饰者抽象类
1// 咖啡装饰者抽象类,实现咖啡接口并持有一个咖啡接口的引用
2public abstract class CoffeeDecorator implements Coffee {
3 protected Coffee decoratedCoffee;
4
5 public CoffeeDecorator(Coffee coffee) {
6 this.decoratedCoffee = coffee;
7 }
8
9 @Override
10 public String getDescription() {
11 return decoratedCoffee.getDescription();
12 }
13
14 @Override
15 public double getCost() {
16 return decoratedCoffee.getCost();
17 }
18}
步骤4:实现具体装饰者
1// 摩卡装饰者,添加摩卡调料的功能
2public class MochaDecorator extends CoffeeDecorator {
3 public MochaDecorator(Coffee coffee) {
4 super(coffee);
5 }
6
7 @Override
8 public String getDescription() {
9 return decoratedCoffee.getDescription() + ", Mocha";
10 }
11
12 @Override
13 public double getCost() {
14 return decoratedCoffee.getCost() + 2; // 添加摩卡调料的成本
15 }
16}
17
18// 奶泡装饰者,添加奶泡调料的功能
19public class WhipDecorator extends CoffeeDecorator {
20 public WhipDecorator(Coffee coffee) {
21 super(coffee);
22 }
23
24 @Override
25 public String getDescription() {
26 return decoratedCoffee.getDescription() + ", Whip";
27 }
28
29 @Override
30 public double getCost() {
31 return decoratedCoffee.getCost() + 1; // 添加奶泡调料的成本
32 }
33}
34
35// 其他装饰者类似...
步骤5:客户端代码使用装饰者
1public class DecoratorPatternDemo {
2 public static void main(String[] args) {
3 Coffee coffee = new SimpleCoffee();
4 System.out.println(coffee.getDescription() + " Cost: $" + coffee.getCost());
5
6 coffee = new MochaDecorator(coffee);
7 System.out.println(coffee.getDescription() + " Cost: $" + coffee.getCost());
8
9 coffee = new WhipDecorator(coffee);
10 System.out.println(coffee.getDescription() + " Cost: $" + coffee.getCost());
11
12 // 可以继续添加更多装饰者
13 // coffee = new SoyDecorator(coffee);
14 // System.out.println(coffee.getDescription() + " Cost: $" + coffee.getCost());
15 }
16}
在此实践案例中,CoffeeDecorator 类提供了一个包装咖啡对象的功能。具体的装饰者类(如 MochaDecorator 和 WhipDecorator)添加了额外的行为和成本。通过这种方式,我们可以组合不同的装饰者来创建多种咖啡变体,而无需为每一种组合创建一个新类。
装饰者模式是一种灵活的替代方案,相比生成子类更为优雅。这种模式非常适合用于扩展类的功能,特别是当我们希望在运行时能够动态地添加或删除功能时。此模式也遵循开闭原则,因为我们可以添加新的装饰者类而不修改现有代码。