策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

这个模式涉及到三个角色:

  • 环境(Context)角色:持有一个Strategy的引用。
  • 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
  • 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
public class Context {
    //持有一个具体策略的对象
    private Strategy strategy;
    public Context(Strategy strategy){
        this.strategy = strategy;
    }
    /**
     * 策略方法
     */
    public void contextInterface(){
        strategy.strategyInterface();
    }
}
public interface Strategy {
    /**
     * 策略方法
     */
    public void strategyInterface();
}

下面是具体的策略

public class ConcreteStrategyA implements Strategy {
    @Override
    public void strategyInterface() {
        //相关的业务
    }
}
public class ConcreteStrategyB implements Strategy {
    @Override
    public void strategyInterface() {
        //相关的业务
    }
}

使用:

public class Client {
    public static void main(String[] args) {
        //选择并创建需要使用的策略对象
        ConcreteStrategyA strategyA = new ConcreteStrategyA();
        //创建环境
        Context context = new Context(strategyA);
        context.contextInterface();
        //当然,这里可以根据不同业务需求使用不同的Strategy实例
    }
}

在Spring中,完全可以交由容器去实例化这些策略。然后可以使用注入的方式,使用HashMap来实现Context类。或者更简单的,直接在一个类里面写不同策略方法,使用HashMap + Lambda表达式来实现相同功能。

@Service
public class Test{
    private Map<String,Function> strategy = new HashMap<>();
    @PostConstruct
    public void init(){
        strategy.put("A",this::strategyA);
        strategy.put("B",this::strategyB);
    }

    public void strategyA(){

    }

    public void strategyB(){
        
    }
}

大概长这样。

职责链模式
解决更多的是 条件属于模糊的判断,执行不同的逻辑,比如if(true || false) / else if() /…将判断条件内置于函数中,条件不符合需要链式传递继续执行函数

策略模式
有确定的判断条件,比如switch...case直接根据确定的判断条件调用