裝飾者模式(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)添加了額外的行為和成本。通過這種方式,我們可以組合不同的裝飾者來創建多種咖啡變體,而無需為每一種組合創建一個新類。
裝飾者模式是一種靈活的替代方案,相比生成子類更為優雅。這種模式非常適合用于擴展類的功能,特別是當我們希望在運行時能夠動態地添加或刪除功能時。此模式也遵循開閉原則,因為我們可以添加新的裝飾者類而不修改現有代碼。