概述
裝飾器模式:在原有結構,動態地為對象添加職責,它是一種靈活的擴展功能方式。
業務場景:創建訂單
假設你正在開發一個電商系統,用戶在創建訂單時可以選擇不同的服務(如折扣、配送、禮品包裝等)。你需要靈活地計算訂單的總價,并能夠動態地添加或移除這些服務。
核心思想
在創建訂單場景中的核心思想是動態擴展,它通過組合而非繼承的方式,創建時能不斷擴展,訂單對象傳進入參不斷擴展。
1. 基礎組件接口 (Order
)
public interface Order {double getTotalPrice(); // 獲取訂單總價String getDescription(); // 獲取訂單描述 }
2. 具體組件 (BasicOrder
)
public class BasicOrder implements Order {private double basePrice; // 訂單基礎價格public BasicOrder(double basePrice) {this.basePrice = basePrice;}@Overridepublic double getTotalPrice() {return basePrice; // 返回基礎價格}@Overridepublic String getDescription() {return "基礎訂單(價格:" + basePrice + ")";} }
3. 裝飾器基類 (OrderDecorator
)
public abstract class OrderDecorator implements Order {protected Order decoratedOrder;public OrderDecorator(Order order) {this.decoratedOrder = order;}@Overridepublic double getTotalPrice() {return decoratedOrder.getTotalPrice();}@Overridepublic String getDescription() {return decoratedOrder.getDescription();} }
4. 具體裝飾器?
折扣裝飾器?DiscountDecorator
public class DiscountDecorator extends OrderDecorator {private double discountRate; // 折扣率public DiscountDecorator(Order order, double discountRate) {super(order);this.discountRate = discountRate;}@Overridepublic double getTotalPrice() {return super.getTotalPrice() * (1 - discountRate); // 應用折扣}@Overridepublic String getDescription() {return super.getDescription() + " + 折扣(" + (discountRate * 100) + "%)";} }
加急配送裝飾器?ExpressShippingDecorator
public class ExpressShippingDecorator extends OrderDecorator {private double expressShippingFee; // 加急配送費用public ExpressShippingDecorator(Order order, double expressShippingFee) {super(order);this.expressShippingFee = expressShippingFee;}@Overridepublic double getTotalPrice() {return super.getTotalPrice() + expressShippingFee; // 添加加急配送費用}@Overridepublic String getDescription() {return super.getDescription() + " + 加急配送(費用:" + expressShippingFee + ")";} }
禮品包裝裝飾器?GiftWrapDecorator
public class GiftWrapDecorator extends OrderDecorator {private double giftWrapFee; // 禮品包裝費用public GiftWrapDecorator(Order order, double giftWrapFee) {super(order);this.giftWrapFee = giftWrapFee;}@Overridepublic double getTotalPrice() {return super.getTotalPrice() + giftWrapFee; // 添加禮品包裝費用}@Overridepublic String getDescription() {return super.getDescription() + " + 禮品包裝(費用:" + giftWrapFee + ")";} }
5. 客戶端代碼
public class OrderSystem {public static void main(String[] args) {// 創建一個基礎訂單Order order = new BasicOrder(100.0);System.out.println(order.getDescription());System.out.println("總價: " + order.getTotalPrice());// 添加折扣order = new DiscountDecorator(order, 0.1); // 10% 折扣System.out.println(order.getDescription());System.out.println("總價: " + order.getTotalPrice());// 添加加急配送order = new ExpressShippingDecorator(order, 15.0); // 加急配送費用 15System.out.println(order.getDescription());System.out.println("總價: " + order.getTotalPrice());// 添加禮品包裝order = new GiftWrapDecorator(order, 5.0); // 禮品包裝費用 5System.out.println(order.getDescription());System.out.println("總價: " + order.getTotalPrice());} }
6. 輸出
基礎訂單(價格:100.0) 總價: 100.0 基礎訂單(價格:100.0) + 折扣(10.0%) 總價: 90.0 基礎訂單(價格:100.0) + 折扣(10.0%) + 加急配送(費用:15.0) 總價: 105.0 基礎訂單(價格:100.0) + 折扣(10.0%) + 加急配送(費用:15.0) + 禮品包裝(費用:5.0) 總價: 110.0
業務場景總結
-
問題:訂單可能需要添加多種附加服務(如折扣、運費、包裝費等),如果為每種組合創建單獨的類,會導致類爆炸。
-
解決方案:使用裝飾器模式,動態地為訂單添加附加服務。
-
優點:
-
靈活擴展功能,無需修改訂單類的核心邏輯。
-
支持動態添加或移除服務,符合開閉原則。
-
避免類爆炸,組合功能更加簡潔。
-
其他業務場景
-
購物車:為購物車動態添加優惠券、滿減活動等。
-
訂閱服務:為用戶訂閱動態添加附加功能(如高級功能、額外存儲等)。
-
賬單系統:為賬單動態添加稅費、服務費等。
裝飾器模式在創建訂單場景中的核心思想是動態擴展,它通過組合而非繼承的方式,靈活地為訂單添加功能或服務。