2020.01.30
故事說明:
今天你接到一個需求,星X客咖啡要你幫忙設計點餐系統,針對不同咖啡給要求得出不同價格,一開始這樣設計….
有一個抽象基類,讓夠種不同的飲品繼承,在實踐cost方法,
這樣設計好嗎?不好,這樣爛透了QQ,如果顧客要求配料如加糖的、摩卡口味的,那樣怎麼辦,通通列舉實踐出來嗎,這樣的組合有大量的類別需要建立,光是摩卡就有,摩卡加糖不加奶、摩哪加糖加奶、摩卡不加糖不加奶……?
以下缺點
- 如果牛奶價格有變化,那所有有關牛奶的類別都要修改。
- 如果要新增一款配料,類別複雜度會成指數上升。
改進看看…..
那我就添加幾類裡的私有布林變數,給予加糖、摩卡、奶油….再根據布林各自計算價格,這樣設計呢?
以下缺點
- 配料價格改變我們需要更改程式碼
- 一但出現新配料,就要加入新的方法
- 如果有人要雙倍摩卡?那怎麼辦
這時候,裝飾者模式登場了
裝飾者模式
1.定義
動態的將責任加諸在物件上,如果要擴充功能,裝飾者提供了比繼承更有彈性的選擇。
2.改進原本程式
- 建立所有物件的基底類別與配料基底類別
2.寫出飲料程式碼
3.寫出配料程式碼
4.輸出測試
在線Demo:https://dotnetfiddle.net/fofF2s
Peter:透過裝飾者,就能動態的組合類別,真的好方便。
3.裝飾模式適用場景
(1).如果你希望在無需修改程式碼的情況下使用某個物件,且希望在運行時為物件新增額外的行為,可以使用裝飾者模式。
(2).使用繼承來擴展物件行為的方案難以實現或不可能,你可以使用。
4.裝飾模式優缺點
優點:
(1).不需要創造新的子類別就可以擴展物件行為。
(2).可以僅在運行時添加或刪除某個物件的行為。
(3).可以多用幾個裝飾封裝物件來組合多種行為。
(4).單一職責原則,可以將實現了許多不同行為的一個大類別拆分成許多較小的類別。
缺點:
(1).要在封裝器中刪除特定封裝器比較困難
(2).實現行為不受裝飾棧順序影響的裝飾比較困難。
(3).各層的初始化配置程式碼看上去會有點可怕。
Reference
Head First Design Patterns
作者:Elisabeth Freeman, Eric Freeman, Bert Bates, Kathy Sierra 著