策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
这个模式涉及到三个角色:
- 环境(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直接根据确定的判断条件调用