##问题
假定你们公司要做一套模拟鸭子游戏:SimUDuck。游戏中会出现各种鸭子,一边游泳戏水,一边呱呱叫。
你想哈,这还不简单,我只要设计一个鸭子超类,并让各种鸭子继承此超类即可。呼哧呼哧,你撸起袖子就写下如下设计类图:
但有一天,你的leader心血来潮,觉得应该加点功能,应该加入会飞的鸭子。这时你想,这也不难,只需加个方法不就完了么。
这时就有问题了,橡皮鸭子(RubberDuck)居然满屏飞了。
显然这种设计的可扩展性非常差。
这时就涉及到OO设计中的一个重要原则——封装变化
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起
我们发现fly和quack并不是所有鸭子的共性,故将它们抽离出来。
设计两个接口:FlyBehavior, QuackBehavior。然后实现FlyWithWings和FlyNoWay两个类,一个表示会飞,一个不会飞。同理,我们实现三种代表三种不同叫的行为的类。
这时,考虑另一个重要的原则——多用组合,少用继承
这样设计有什么优势呢。显然,以后如果要增加新的行为,只要写一个新的行为类,并在Duck类里加一个对应的行为属性就可以了。这样,我们就把“行为”委托给一些类来处理。
这样,既保留了继承的复用性又拥有了可扩展性。
##总结
###设计原则
- 封装变化
- 多用组合,少用继承
- 针对接口编程,不针对实现编程
###策略模式
定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。