策略链模式,也叫政策模式,是一种简单的模式。
一.策略模式的现实场景
蔡梁如愿成为了一名警察并被分配到了重案组,他刚刚调到重案组就参加了一个重大案件,这次案件需要剿灭一个贩毒团伙。因为这个贩毒团伙非常狡猾,重案组为力确保万无一失,一击即灭整个贩毒团伙,他们针对有可能发生的情况制定了多项计划,最终经过 激烈讨论他们确定了A、B、C三套计划。确定计划后,蔡梁就跟同事一起参加了这次的围剿行动,并且最终将整个贩毒团伙一网打尽。
上面的这个场景中,针对围剿贩毒团伙可能发生的情况,重案组确定了A、B、C三套计划,但是贩毒团伙并不会知道,这个就类似于设计模式中的策略模式。
二.策略模式(Strategy Pattern)的定义
定义一组算法,将每个算法封装起来,并且使他们之间可以互换。其用意是针对一组算法,将每个算法封装到具有共同接口的独立类中,从而使得它们可以相互转换,使得算法可以在不影响客户端的情况下发生变化。
三.策略模式的类图
四.策略模式的三个角色
1.环境(Context)角色
该角色也叫上下文角色,有承上启下的作用,屏蔽高层模块堆策略、算法的直接处理,他持有一个Strategy类的应用。
2.抽象策略(Strategy)角色
该角色对策略、算法进行抽象,通常定义每一个策略或算法具有的方法和属性。
3.具体策略(Concrete Stategy)模式
该角色实现抽象策略中的具体操作,含有具体的算法。
五.策略模式的优缺点
策略模式中的优点
1. 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族,恰当地使用继承可以把公共的代码移到父类中,从未避免代码重复。
2. 策略模式提供了可以替换继承关系的方法。继承可以处理多种算法或行为。
3.策略模式可以避免使用多重条件转移语句。多重条件转移语句不易维护,它把采用哪一种算法或采取哪一种行为的逻辑与算法的逻辑混在一起,统列在一个多重条件转移语句里面,这比使用继承的方法还要原始和落后。
策略模式的缺点
1.客户端必须知道所有的策略类,并自行决定使用哪一种策略。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。即策略模式只适合于客户端知道所有的算法或行为。(这里客户端指的是我们程序员!)
2.策略模式造成很多策略类。有时候可以通过把依赖于环境的状态保持到客户到里面,同时将策略模式设计成共享的,这样策略实例就可以别不同客户端使用。可以使用享元模式来减少对象的数量。
六.策略模式的使用场景
1.多个类只是在算法或行为上稍微有不同的场景。
2.算法需要自由切换的场景。
3.需要屏蔽算法规则的场景。
七.策略模式的示例
这里使用上面的现实场景做代码示例。
示例的类图
方法的作用看代码。。。
示例的代码
策略抽象类StrategyForPlan
package P16_stategy;
/**
* 策略抽象类
*/
public abstract class StrategyForPlan {
//抽象的围剿计划
public abstract void plan();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
A计划
package P16_stategy;
/**
* A计划
*/
public class APlan extends StrategyForPlan {
@Override
public void plan() {
System.out.println("执行A计划");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
B计划
package P16_stategy;
/**
* B计划
*/
public class BPlan extends StrategyForPlan {
@Override
public void plan() {
System.out.println("执行B计划");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
C计划
package P16_stategy;
/**
* C计划
*/
public class CPlan extends StrategyForPlan {
@Override
public void plan() {
System.out.println("执行C计划");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
上下文类,测试类
package P16_stategy;
/**
* 测试类,上下文类
*/
public class ContextPlan {
private StrategyForPlan strategyForPlan;
public ContextPlan(StrategyForPlan strategyForPlan){
this.strategyForPlan=strategyForPlan;
}
public void actionPlan(){
strategyForPlan.plan();
}
public static void main(String[] args){
//制定出三种方案
StrategyForPlan aPlan=new APlan();
StrategyForPlan bPlan=new BPlan();
StrategyForPlan cPlan=new CPlan();
System.out.println("默认执行A计划");
//执行A计划
ContextPlan realPlan=new ContextPlan(aPlan);
realPlan.actionPlan();
System.out.println("情况有变需要执行B计划");
//情况有变需要执行B计划
realPlan=new ContextPlan(bPlan);//替换计划
realPlan.actionPlan();//执行计划
System.out.println("最终将贩毒团伙一网打尽。");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
程序运行结果;
策略模式适用于某些特定需求的功能,就像我们百度地图上从一个地方到另一个地方的路线,有时间优先的,有价格优先的,还有路线最短的,都是能帮你到达终点的。。。