策略模式
1. 介绍
1.1 什么是策略模式
定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。
1.2 优点
- 算法可以自由切换。
- 避免使用多重条件判断。
- 扩展性良好。
1.3 缺点
- 策略类会增多。
- 所有策略类都需要对外暴露。
1.4 使用场景
- 多个类只有在算法或行为上稍有不同的场景。
- 算法需要自由切换的场景。
- 需要屏蔽算法规则的场景。
- 简化多重if-else,或多个switch-case分支。(特定情况下)
1.5 策略模式包含以下几个核心角色
- 环境(Context):维护一个对策略对象的引用,负责将客户端请求委派给具体的策略对象执行。环境类可以通过依赖注入、简单工厂等方式来获取具体策略对象。
- 抽象策略(Abstract Strategy):定义了策略对象的公共接口或抽象类,规定了具体策略类必须实现的方法。
- 具体策略(Concrete Strategy):实现了抽象策略定义的接口或抽象类,包含了具体的算法实现。
2. 通用实现
//创建抽象策略类
public interface Strategy {
public int doOperation(int num1, int num2);
}
//创建策略实现
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
//创建策略实现
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
//创建环境
public class Context {
private Strategy strategy;
//动态的替换策略算法
public Context(Strategy strategy){
this.strategy = strategy;
}
//调用
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubtract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
//输出
10 + 5 = 15
10 - 5 = 5
10 * 5 = 50
3. 其他示例
4. 策略模式在JDK中实践
4.1 Arrays.sort函数
/**
*根据传入不同的对比算法排序
* */
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
4.2 ThreadPoolExecutor中的四种拒绝策略
在创建线程池时,需要传入拒绝策略,当创建新线程使当前运行的线程数超过maximumPoolSize时,将会使用传入的拒绝策略进行处理。
AbortPolicy:直接抛出异常。
CallerRunsPolicy:只用调用者所在线程来运行任务。
DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
DiscardPolicy:不处理,丢弃掉。
评论区