什么是策略模式?
策略模式是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定(策略)。策略模式主要用来平滑地处理算法的切换 。
策略模式的结构图(来自百度)
Strategy接口,定义所有支持的算法的公共接口
// 算法接口类
public interface Strategy {
// 算法方法
public abstract void algorithmInterface();
}
ConcreteStrategy*:封装了具体的算法或行为,继承于 Strategy
// 具体算法A
public class ConcreteStrategyA implements Strategy {
// 算法A实现算法
@Override
public void algorithmInterface() {
System.out.println("算法A实现");
}
}
// -----------------------
// 具体算法B
public class ConcreteStrategyB implements Strategy {
// 算法A实现算法
@Override
public void algorithmInterface() {
System.out.println("算法B实现");
}
}
Context:用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用
// 算法配置上下文,用于配置具体的Strategy
public class Context {
private Strategy strategy;
// 初始化时传入具体的策略对象
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void operation(){
// 根据具体的对象调用其实现方法
strategy.algorithmInterface();
}
}
客户端代码:
public class MainClass {
public static void main(String[] args) {
Context context;
context = new Context(new ConcreteStrategyA());
context.operation();
context = new Context(new ConcreteStrategyB());
context.operation();
}
}
代码改造(策略与简单工厂结合):
Context:
// 算法配置上下文,用于配置具体的Strategy
public class Context_2 {
private Strategy strategy;
// 初始化时传入具体的策略对象名称,由上下文判断使用哪个具体的策略,并创建该具体的策略
public Context_2(String strategyName) {
switch (strategyName){
case "ConcreteStrategyA":
strategy = new ConcreteStrategyA();
break;
case "ConcreteStrategyB":
strategy = new ConcreteStrategyB();
break;
}
}
public void operation(){
// 根据具体的对象调用其实现方法
strategy.algorithmInterface();
}
}
客户端代码:
public class MainClass_2 {
public static void main(String[] args) {
Context_2 context = new Context_2("ConcreteStrategyA");
context.operation();
context = new Context_2("ConcreteStrategyB");
context.operation();
}
}
改造之后客户端只需要知道一个Context类即可。降低代码耦合度。
策略模式的优点
1. 策略模式是一种定义一系列算法的方法,从概念上来看,所有的这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法与使用算法类之间的耦合。
2. 策略模式的Strategy类层为Context定义了一系列的可供重用的算法或者行为。继承有助于分析出这算法的公共功能。
3. 策略模式简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
策略模式的缺点:
对于客户端来说他必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须能理解这些策略的区别以便在合适的场景使用。
策略模式的使用场景:
策略模式就是用来封装算法的,在实践中,我们可以发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化。