深入淺出設計模式讀後心得_裝飾者模式

  • 4653
  • 0

裝飾者模式:
動態地將責任附加到對象上,若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。

裝飾者模式:
動態地將責任附加到對象上,若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。

書中以星巴茲咖啡為例(這算是暗示性的置入性行銷嗎?XD)
當咖啡有好幾個種類又有一堆配料(擴展功能)的時候,如果用繼承的方式,勢必會多出一堆類別
而且不能動態的在執行階段使用擴展功能(增加配料)

如果把咖啡種類設計成類別,再把是否有加入各項配料當成屬性,那就會引發幾個問題:
1.改變配料價錢會改變現有代碼
2.一旦出現新的配料,就要加上新的屬性
3.日後開發新的飲料,可能要繼承一些不合適的配料屬性
4.顧客想要任意調配飲料,怎麼辦?

設計原則:
類別應該對擴展開放,對修改關閉

但書中的問答也談到:通常沒有辦法讓設計的每個部份都遵守開放-關閉原則
現實中沒有閒功夫這樣搞,而且遵守這個原則,通常會引入新的抽象層次,
增加代碼的複雜度,所以只要把這個原則應用在最有可能改變的地方就好

至於哪裡才是最有可能改變的地方?就牽涉到設計的經驗和Domain Know How了
畢竟只有累積豐富的經驗才能引導出好的設計
(雖然現實中的使用者可能還是會搞一些讓人摸不著、猜不透的古怪想法和需求,但我想因應使用者需求變更的系統總避免不了要搞一下"重構")

基於以上的原則,我們要將咖啡的配料屬性抽出來,並且實做成可以在執行階段動態的加到咖啡上
首先要做一個抽象的超類別:


再來做一個濃縮咖啡類別繼承上面的Beverage:


然後是配料的抽象類別,同樣繼承Beverage:


接著是Mocha配料類別,繼承上面的CondimentDecorator


執行的時候就像下面這樣"裝飾":


書中最後的咖啡大小解答,會造成判斷咖啡大小的相同邏輯不斷在配料類別中上演
但礙於還沒提到後面的設計模式,所以也不能這邊挑它這個毛病

下面附上的是我自己用點餐的想法寫出來的程式碼,看起來會跟書上面的不太一樣
各位看倌若有好的建議,還請不吝提出^^
Decorator Pattern Sample.rar