Re: [模式] 請問 Decorator Pattern 的應用

作者: leondemon (狗狗)   2010-04-03 18:08:05
※ 引述《chchwy (mat)》之銘言:
: 有沒有某些情境下
: 非常恰巧適合應用decorator
: 否則程式就會變得很醜很難維護的例子
其實沒有必要將design pattern跟某些情境(需求)綁死 因為情境是活的
最簡單的方式就是把所有pattern都弄懂弄熟 自然而然就會開始調用適合的pattern
因為有時候需求改變時 就會改變原本所使用的pattern
甚至使用混合不同種的pattern或衍生出新pattern 來應付新的問題或狀況
在一開始你對改變的需求很少的時候 都會使用簡單易用的pattern (甚至是不用)
當你發現問題越來越複雜 日後維護不容易的時候 表示應該會有更好的方法可以去撰碼
所以並不表示當你使用了一個pattern 以後都會在這個地方使用這個pattern...
這些都會因為當需求的「範圍(或說是"等級")」改變時 而調用適合的pattern
例如 假如你在類別A有個方法叫aMethod
假如你期望A的aMethod只會有一種結果 那你可以直接把實作寫在aMethod裡面
如果你期望A的aMethod可以動態的改變它「整個」功能 那就可以使用strategy pattern
假如你期望A的aMethod的功能(或說演算法)可以去動態的「微調」它的細節
那你就可以使用decorator pattern 因為你可以將各細節自由抽換做改變
還有一堆假如... 這些都端看你的需求而決定你要用什麼樣的pattern
如果你一開始就想得很遠 為了應付以後的變化 而一開始就設計使用複雜的pattern
那就可以避免將來面對到越來越多的需求改變時 需要重新refactor的命運
decorator pattern的精髓 在於一個method裡面 存在著許多「同等級」的程式碼
這些不同區塊所實作的同等級程式碼 應該由不同的類別去負責維護
我一時想不到要用什麼樣的字句來表達這上面兩句 所以用別人的例子來說明:
假設你去速食店點餐,想要點了一份炸雞、薯條、可樂、牛肉漢堡、玉米濃湯來吃
假如很幸運的 剛好有這樣一份套餐可以點 那麼這就是使用了strategy pattern
因為他們將這些套餐內容寫在一個strategy裡面包好 可以給客戶任意選擇使用
而strategy所提供的套餐選擇可以有很多種 所以就會有A餐、B餐、C餐...等
但是很不幸的 今天沒有一個套餐可以符合你的需求 所以你必須「單點」
於是提供「單點」的服務 就是使用了decorator pattern
因為這些能夠單點食物都是一種「食物商品」 所以他們就是我說的「同等級」
所以這些「單點項目」都是一種decorator
收銀機/服務生(或甚至是發票)即可以利用decorator來記錄你這次點餐的行為
並且分別「獨立」的根據它的價格 去算總共的價錢
也可以「獨立」的呼叫各個負責的工作人員 去製作你所點的各種單點項目
他們動態的「包裝」你的需求 並將你點的食物如同「套餐」一樣放在一個提盤
(像套餐一樣的意思是:客戶只要跟一位服務生叫餐=>使用者只需要呼叫一個method
客戶會拿到一份完整的餐點=>使用者可獲得想要的功能或回傳值
站在櫃檯的服務生=>就是即將被decorated的concrete component
於是對一個服務生開始點餐(method)你就會先獲得一個空的餐盤
負責製作各餐點的工作會有不同的工作人員=>各類別的decorator
然後各工作人員的回傳值就是你的單點項目 最後都會放在空盤上)
所以decorator pattern其實就只是把一個method的功能 給「分工」而已...
strategy pattern就只是一個單純的套餐 只有固定的選擇(當然你可以增加新的套餐!)...
另外一個例子 也就是decorator的本意 就是穿服裝...
當你穿了什麼樣的衣服、褲子、鞋子、手錶、耳環、項鍊等....
他們都是一種穿戴在人身上的「同等級」的裝飾物
所以你要將這些搭配在一起來照鏡子看看搭配是否好看時
你需要能夠動態的抽換身上某個裝飾品 (所以你需要decorator pattern)
而不是為了要換個耳環 就要將全身脫掉再重新穿 (這樣就變成strategy pattern)
當然 西裝時常是成套的(西裝褲+西裝外套) 所以西裝部分可以是strategy
然後再和不同的襯衫、領帶、皮鞋、皮帶等混成decorator
這時候就是將兩種以上的pattern混合使用
然後各家西裝店都會在窗櫃擺設一些假人偶 並且套上一些「已經搭配好」的服裝
其實這個將單品預先組裝好的過程 就是factory pattern系列
其實design pattern可以用來說明很多生活上的行為
用生活化的思維去學design pattern會比較容易

Links booklink

Contact Us: admin [ a t ] ucptt.com