在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
意图:
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。主要解决:
在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。何时使用:
一个系统有许多许多类,而区分它们的只是他们直接的行为。如何解决:
将这些算法封装成一个一个的类,任意地替换。关键代码:
实现同一个接口。应用实例 :
1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。3、JAVA AWT 中的 LayoutManager。优点 :
1、算法可以自由切换。2、避免使用多重条件判断。3、扩展性良好。缺点:
1、策略类会增多。2、所有策略类都需要对外暴露。使用场景 :
1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。2、一个系统需要动态地在几种算法中选择一种。3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。注意事项:
如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题下面用不同鸭子的飞行策略来演示
定义飞行策略接口和每个飞行策略
/** * 飞行策略接口 */ public interface FlyStrategy { //飞行方法 void fly(); } /** * 能飞的策略 */ public class GoodFlyStrategy implements FlyStrategy { @Override public void fly() { System.out.println(" 飞翔技术高超 ~~~"); } } /** * 不能分的策略 */ public class NoFlyStrategy implements FlyStrategy { @Override public void fly() { System.out.println("不会飞翔"); } }定义鸭子的抽象类组合飞行策略和具体的不同鸭子
/** * 抽象鸭子类 */ public abstract class Duck { /** * 组合鸭子的飞行策略接口 */ FlyStrategy flyStrategy; /** * 飞行 */ public void fly() { if (flyStrategy != null) { flyStrategy.fly(); } } /** * 动态设置飞行策略 * * @param flyBehavior */ public void setFlyBehavior(FlyStrategy flyBehavior) { this.flyStrategy = flyBehavior; } } /** * 玩具鸭子 */ public class ToyDuck extends Duck { /** * 构造是设置不能飞行的策略 */ public ToyDuck() { flyStrategy = new NoFlyStrategy(); } } /** * 野鸭子 */ public class WildDuck extends Duck { /** * 构造是设置成可以飞行的策略 */ public WildDuck() { flyStrategy = new GoodFlyStrategy(); } }客户端
public class Client { public static void main(String[] args) { //野鸭子 System.out.println("野鸭子==="); WildDuck wildDuck = new WildDuck(); wildDuck.fly(); //玩具鸭子 System.out.println("玩具鸭子==="); ToyDuck toyDuck = new ToyDuck(); toyDuck.fly(); // 动态的改变鸭子的飞行策略 System.out.println("野鸭子吃胖了==="); wildDuck.setFlyBehavior(new NoFlyStrategy()); wildDuck.fly(); } }