抽象的鸭子,有几个子鸭子类继承了
来了个变态需求:我们要鸭子会飞(本人见过)
比较好想的解决方法是:在抽象鸭子中加个fly方法
解决了,生活真美好,感谢继承感谢cctv
有看官说了:等等,我家儿子的橡胶玩具鸭子也继承了你那个类了,它不会飞啊
…… 呃,在你的玩具鸭子上覆写fly方法就好了嘛,表烦我
我们家还有诱饵鸭子,不飞也不叫,木头的
…… 你家鸭子真BT
教训:在超类上加上新的行为,会使某些不适合该行为的子类也具有该行为
看来维护的时候,为了reuse而使用的继承,还真有点问题
大师原则:针对接口编程
好的,我把fly从抽象鸭子里提出来放在个接口里,想飞的鸭子去实现吧
但是,太多的鸭子类可能要写相同的fly方法,代码太多了吧,呃。。。好像还不如继承来的方便
大师原则:多用组合,少用继承
is-a和has-a,不继承的话,我们就has-a吧
OK,接口仍然存在,想飞的鸭子类可以持有该接口做为一个属性,并且委托接口的不同实现去fly
不管你是想用翅膀飞,还是想坐飞机飞,还是火箭动力飞,只要把不同的实现插接到鸭子上,
而鸭子代码不用做任何改变就可以随便怎么飞,这就是抽象的好处
大师原则:封装变化
呃。。。。那不用继承,抽象鸭子类也应该做成接口吗?
我们处理的变化的部分,固定不变的部分,让它们被继承好了,我们甚至可以把被继承的类做成具体类。
我们不可能预料到所有的变化,如果出现了新了变化,做上面同样的处理就是了。
目前,我们解决了原先变化的问题,这样就可以了,要有个度,没有必要全部来抽象,会提高不必要的复杂度。
关键:处理变化的部分
而飞的行为被抽出来,跟鸭子没有什么关系。
老母鸡也想飞?OK,用飞的接口声明个属性去,我这里有翅膀火箭喷气等等各种飞,拿去插到你的类中
面向对象向我们承诺了“复用”,有很多方法,但继承是种强耦合,所以我们用组合
OO强烈追求的目标是:解耦,把会变化的部分抽出并封装起来,
以期让系统中某部分的改变不影响到其它部分,几乎每个模式都体现出这种精神,并提供一种方式来实现此目标。
这里,我们得到了“
策略
”模式
正式定义是
:策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,
此模式让算法的变化独立于使用算法的客户
ps:这是我最喜欢的模式