概述
由于环境/条件的不同,完成某一项任务往往有不同的算法,每一个算法称为一个策略,我们定义一些独立的类来封装不同的算法,这些类称为策略Strategy。

该模式下的角色有:
(1)抽象策略角色:通常是一个接口或抽象类
(2)具体策略角色:实现策略接口或继承抽象类。它包装了相关的算法。
(3)环境/条件角色Context:它持有一个策略接口/抽象类的引用strategy。根据传入参数strategy的不同,它会调用不同的策略。
示例
假设两个数的计算方式分为加法和减法,现给出一个式子:
num1 @ num2,其中 @ 符号表示加法或减法。我们用代码来实现这个策略
首先定义抽象策略角色——计算方式接口Strategy:
public interface Strategy {
int doOperation(int num1, int num2);
}
然后是具体策略角色——两个计算方式接口的实现类:加法类和减法类
public class AddOperation implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
public class SubstractOperation implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
然后是环境/条件类Context,可以将它理解为符号@,它持有一个策略类,
public class Context {
private Strategy strategy;
public Context() { }
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public int computing(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
测试一下:
public class Test {
public static void main(String[] args) {
Context context = new Context();
context.setStrategy(new AddOperation());
System.out.println("3 + 33 = " + context.computing(3, 33));
context.setStrategy(new SubstractOperation());
System.out.println("3 - 33 = " + context.computing(3, 33));
}
}
总结
优点
(1)可以根据条件Context对象的不同来选择不同策略。
(2)避免使用多重条件判断
(3)扩展性良好,若要新加一个策略,直接新写一个具体策略类即可。
缺点
(1)策略类可能会增多,且所有的策略类需要对外暴露。
线程池中的策略模式
在线程池的构造函数中,有一个RejectedExecutionHandler类型参数对象handler,它表示拒绝策略,有四种实现方式:
- 直接抛出异常
- 使用调用者的线程来处理
- 直接丢掉这个任务
- 丢掉最老的任务
private volatile RejectedExecutionHandler handler;
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
//省略部分代码
this.handler = handler;
}
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}