设计模式第一弹,发现在继续学习Java相关知识前,很有必要学习下设计模式,其中几个比较重要的设计模式其实在之前的使用中已经出现过很多次,但是由于没有学过设计模式,也就知其然不知其所以然的拿来用了,所以接下来准备好好整理学习设计模式,博客整理的内容均来自《Head First 设计模式》。下面开始整理第一个设计模式–策略模式
1.概念
策略模式:针对一组算法,将每一个算法分别封装起来,让它们之前可以互相替换,此模式让算法的变化独立于使用算法的客户。
2.设计原则
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。即:封装变化
把会变化的部分取出并“封装”起来,以便以后可以轻易地改动或扩充此部分,而不影响到不需要变化的其他部分,总结起来就是:分开变化和不会变化的部分。针对接口编程,而不是针对实现编程
将需要变化的行为放在分开的类中,此类专门提供某种行为接口的实现。多用组合,少用继承
区分“有一个”(组合)关系和“是一个”(继承)关系,使用 组合建立系统具有很大的弹性,不仅可以将算法族封装成类,更可以“在运行时动态的改变行为”。
3.使用举例
借用《Head First 设计模式》书上的实例:
3.1 假设鸭子类(Duck),有许多不同的子类:
绿头鸭(MallardDuck)
红头鸭(RedHeadDuck)
橡皮鸭(RubberDuck)
诱饵鸭(DecoyDuck)
模型鸭(ModelDuck)
子类继承父类的行为:呱呱叫(quack())和游泳(swim())
嗯,一切看起来都很正常,通过继承,子类得到父类的行为,这样子类也会呱呱叫和游泳;
3.2 现在想让某些鸭子具有新的行为:飞行(fly())
首先想到的是在需要具有飞行行为的子类中添加新的方法(fly())不就解决了吗!嗯,这是在子类比较少的情况下可以使用的“笨办法”,一旦子类很多,而且也许好几个子类具有的飞行行为是一样的呢?这样不就产生了大量重复代码吗?这是我们需要避免的!
其次想到的是在父类(Duck)中添加行为(fly()),其子类通过继承就拥有飞行行为了。看似问题解决了,但是想想这样子所有的子类就都拥有了飞行的行为,包括橡皮鸭(不应该具有飞行的行为),所以这种方法行不通,因为通过继承,一旦改变父类中的某些行为,所有子类都将受影响,导致某些不应该变化的子类也发生了变化,这种改变将是牵一发而动全身的;
通过继承来提供Duck的行为的缺点:- 导致代码在多个子类中重复
- 运行时的行为不容易改变
- 很难知道所有鸭子的全部行为
接下来想到的方法是通过接口实现,通过将变化的行为(呱呱叫,游泳,飞行