定义
定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换,本模式使得算法可独立于使用它的客户而变化。
例如我们生活中出行可以选择火车,飞机,私家车等方式,每一种出行方式就可以看做一种策略。
结构
- Strategy,策略接口,用来约束一系列具体的策略接口。
- ConcreteStrategy,具体策略实现类,提供具体的算法实现。
- Context,上下文,负责和具体的策略类交互。
简单实现
策略接口
public interface Strategy {
void strategyMethod();
}
具体策略实现类
public class ConcreteStrategyA implements Strategy {
@Override
public void strategyMethod() {
System.out.println("具体策略A执行");
}
}
另一个具体策略实现
public class ConcreteStrategyB implements Strategy {
@Override
public void strategyMethod() {
System.out.println("具体策略B执行");
}
}
上下文
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void strategyMethod() {
strategy.strategyMethod();
}
}
客户端
public class Client {
public static void main(String[] args) {
Strategy strategy = new ConcreteStrategyA();
Context context = new Context(strategy);
context.strategyMethod();
}
}
策略模式在JDK中的实现
JDK中的Comparator接口
import java.util.Arrays;
import java.util.Comparator;
public class Client {
public static void main(String[] args) {
String[] names = {"张三", "李四", "小明"};
Comparator<String> comparator = new Comparator<>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
};
Arrays.sort(names, comparator);
System.out.println(Arrays.toString(names));
}
}
Comparator就是策略接口,使用匿名内部类来实现具体策略类。
总结
优点
- 避免了多重的条件语句,易于维护。
- 更好的扩展性,方便增加新的策略实现,符合开闭原则。
缺点
- 客户端必须了解每种策略的不同才能正确的选择使用哪种策略,这样就暴露了策略的具体实现。
本质
策略模式的本质是分离算法,选择实现。分离并封装了算法,才能够很容易的修改和增加算法,也能很容易的动态切换算法。
具体实现中,可以去掉上下文对象,客户端直接和具体策略交互。
使用场景
- 一个定义了很多行为的类,并且是通过多个if-else语句来选择这些行为的情况,可以使用策略模式来代替这些条件语句。
- 需要动态的切换不同的算法。
参考
大战设计模式【1】—— 策略模式
设计模式的征途—18.策略(Strategy)模式
设计模式(二十三)——策略模式(Arrays源码分析)
设计模式——策略模式
策略模式(策略设计模式)详解
研磨设计模式-书籍