【图解设计模式系列】The Strategy Pattern: 策略模式
当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。讲这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。(大概的意思就是说 我们要多多利用多态 而不是用大量的if else语句)
策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式进行处理这种变化的可能性。
说了一堆P话。
简而言之 就是:
简单理解就是一组算法,可以互换,再简单点策略就是封装算法。
但是这也太精简了,究竟是什么意思呢?

看上去很乱 是不是?
下面分析一下这个模式包含哪些角色:
**环境(Context)**角色:持有一个Strategy的引用。
**抽象策略(Strategy)**角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
**具体策略(Concrete Strategy)**角色:包装了相关的算法或行为。
实例
假设某人在开车时频繁加速,因为超速他被一个警察拦下来了。有可能这个警察会比较友好,没开任何罚单就让他把车开走了。也有可能遇到了一个不太友好的警察,然后这个警察给他出具了一张罚单。但是并不知道会遇到什么类型的警察,直到他因为超速而被警察拦下停车,实际上这就是一种程序当中“运行时”的概念,只有在运行的时候才知道,到底会遇到什么类型的警察,实际上这就是“策略模式”。
//先来定义一个策略的接口:Strategy
public interface Strategy {
public void processSpeeding(int speed);
}
两种不同类型的Strategy:
public class NicePolice implements Strategy {
@Override
public void processSpeeding(int speed) {
System.out.println("This is your first time, be sure don't do it again!");
}
}
public class HardPolice implements Strategy {
@Override
public void processSpeeding(int speed) {
System.out.println("Your speed is " + speed+ ", and should get a ticket!");
}
}
定义需要依赖警察来处理超速问题的场景
public class Situation {
private Strategy strategy;
public Situation(Strategy strategy){
this.strategy = strategy;
}
public void handleByPolice(int speed){
this.strategy.processSpeeding(speed);
}
}
public class Main {
public static void main(String[] args) {
HardPolice hardpolice = new HardPolice();
NicePolice nicepolice = new NicePolice();
// In situation 1, a hard officer is met
// In situation 2, a nice officer is met
Situation s1 = new Situation(hardpolice);
Situation s2 = new Situation(nidepolice);
// the result based on the kind of police officer.
s1.handleByPolice(10);
s2.handleByPolice(10);
}
}
实例中实例
JDK中的策略模式
在创建线程池(ThreadPoolExecutor)时,需要传入拒绝策略,当创建新线程使当前运行的线程数超过maximumPoolSize时,将会使用传入的拒绝策略进行处理。
- AbortPolicy:直接抛出异常。
- CallerRunsPolicy:只用调用者所在线程来运行任务。
- DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
- DiscardPolicy:不处理,丢弃掉。
这里使用的就是策略模式。
优缺点
优点:
- 算法可以自由切换:改一下策略很方便
- 扩展性良好:增加一个策略,就多增加一个类就好了。
缺点:
- 策略类的数量增多:每一个策略都是一个类,复用的可能性很小、类数量增多
- 所有的策略类都需要对外暴露:上层模块必须知道有哪些策略,然后才能决定使用哪一个策略

浙公网安备 33010602011771号