假如今天我們經營一間咖啡店Starbuzz,在沒有被星X克告侵權的情況下,幸運的開了許多分店,經營規模跟著擴大,所以我們需要開發新的點餐系統。
按照先前的設計原則,我們會很直覺地先寫出一個抽象類別 Beverage()
,裡面包含可以算出此飲料成本的抽象方法 cost()
,以及可以拿到此飲料資訊的 getDescription()
。不同的飲料名稱像是Latte()
,就是繼承Beverage()
的子類別,會依照不同飲料成本實作 cost()
。
問題來了,飲料的調味料其實有固定的品項,像是牛奶、抹茶、焦糖糖漿、鮮奶油⋯⋯等,不同飲料成本計算其實就是咖啡和調味料的排列組合。如果用上述方式,難道有一百種飲料就要實作一百次的cost()
?若是有特定調味料價錢更動,必須手動去改一百個子類別的成本嗎?
設計原則:在不改變原有類別的情況下彈性擴充原有程式碼
如果用調飲料來比喻的話,要做出一杯巧克力鮮奶油拿鐵,可以先選擇一個 Beverage()
的飲料基底子類別,例如 Latte()
,再慢慢倒進其他調味料Chocolate()
、whipCream()
。
跟先前做法一樣,咖啡都會繼承 Beverage()
,另外會有 Decorator CondimentDecorator()
,他的子類別就是不同的調味料。所有東西都是繼承相同的類別,我們可以用Decorator去裝飾Beverage()
,既可以得到不同飲料,也不會改變Beverage()
的本質。cost()
在每個類別中代表各自的成本,可以透過它實作不同價格加總的結果,若是單一調味料價格改變,也可以彈性調整。
下篇會繼續講解如何實作這個概念~
Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!