策略模式:分别封装行为接口,实现算法族,超类里面放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能,此模式让行为算法的变化独立于算法的使用者。
注意点:
1.分析项目中变化部分与不变部分
2.多用组合少用继承;用行为类组合,而不是行为的继承。更有弹性
3.设计模式有没有相应的库直接使用?有些库或框架本身就用某种设计模式设计的
策略模式设计到三个角色:
环境角色(Context):持有一个Strategy的引用
抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现,此角色给出所有的具体策略类所需的接口
具体策略(ConcreteStrategy)角色:包装了相关的算法或行为
案例:
模拟飞行的鸭子,设计鸭子超类(Quack、Swim、display),扩展超类
1 | //鸭子超类 |
1 | //绿头鸭 |
1 | //红头鸭 |
1 | //测试类 |
新需求:如果要添加一个飞行功能,一种方法是在超类里添加Fly方法,但是绿头鸭和红头鸭都会实现这个方法,但是并不是所有的鸭子不会飞,这中方法让所有子类都会飞了,这是不科学的。
继承的问题:对类的局部改动,尤其是超类的局部改动,会影响其他部分,影响会有溢出效应。
如果继续用OO原理,子类覆盖超类里Fly的方法,使某个子类实现不会飞行的功能,但是如果有许多子类,那么这也是不可行的。
1 | public void Fly() |
使用策略模式:
抽象策略角色(接口):
public interface FlyBehavior( void fly(); )
public interface QuackBehavior( void quack(); )
环境角色:
1 | public abstract class Duck { |
具体策略角色:在构造方法里就把两个行为定义上,好的飞行,嘎嘎叫,具体的行为不是在类里实现了,而是直接new一个行为族对象。用行为族的对象来展现行为,不是把具体行为写在类的对象里。
1 | public class GreenHeadDuck extends Duck { |
1 | public class GoodFlyBehavior implements FlyBehavior { |
1 | public class GaGaQuackBehavior implements QuackBehavior { |