※ 引述《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会比较容易