策略模式的目的是将不同的策略封装起来,每个策略形成一个一个类文件。你可以进行任意的替换。策略模式遵循开闭原则,意即对扩展保持开放,对修改保持关闭。
当你用springboot的时候,会牵扯到如何将类委托给spring容器,如果你按照策略模式的传统写法,就会遇到类似问题。所以,我们应该将不同的策略实现公用的接口,也就是面向接口编程。
首先,我们定义一个接口。
public interface ICreateOrderAndMissionStrategy {
/**
* 创建订单和任务。不同的策略应该对这个方法进行重写
*/
void doCreateOrderAndMission(KCameraOrderAbstractCreateDTO oscVo);
/**
* 获取类型,每个策略都需要你定义一个类型,比如业务1就定义为1,比如业务2就定义为2。当然,你也可以定义成不同类型。按照你的习惯即可
* @return Integer
*/
Integer getType();
}
然后,构造一个类,这个类的目的就是驱动你的策略。同时,也是这个类将你的策略装配到spring中。
@Service
public class CreateOrderMissionStrategyService {
/**
* 策略类中的成员map变量,保存各种策略类.可以看到我将ICreateOrderAndMissionStrategy接口构造成一个map。通过我之前定义的数字来获取value。也就是能够拿到相应的策略。
*/
Map<Integer, ICreateOrderAndMissionStrategy> strategyMap = new HashMap<>(8);
/**
* 构造函数,通过将spring管理的所有策略类注册进成员map变量中。
* 这个方法很重要,因为它驱动了策略类的装配。
* @param strategies List<ICreateOrderAndMissionStrategy>
*/
public CreateOrderMissionStrategyService(List<ICreateOrderAndMissionStrategy> strategies) {
for (ICreateOrderAndMissionStrategy strategy : strategies) {
strategyMap.put(strategy.getType(), strategy);
}
}
/**
* 处理策略程序。通过strategyType得到我想要的策略类,然后进行调用
* @param strategyType 策略类型
* @param oscVo 业务变量
* @throws BizException 业务异常
*/
public void executeStrategy(Integer strategyType, KCameraOrderAbstractCreateDTO oscVo) throws BizException{
ICreateOrderAndMissionStrategy strategy = strategyMap.get(strategyType);
if(strategy == null){
throw new BizException("未找到事件处理实现类,strategyType:" + strategyType);
}
strategy.doCreateOrderAndMission(oscVo);
}
}
现在,我可以开始根据不同的业务进行不同的策略了。我举两个例子。
//这个是策略A
public class AStrategy implements ICreateOrderAndMissionStrategy {
@Override
public Integer getType() {
return BizEnum.A.getCode(); // 这个是我定义的策略类型的枚举类。我A为1,B为2
}
/**
* A策略的实现逻辑
*/
@Override
public void doCreateOrderAndMission(ParamDTO paramDTO) {
.........
}
}
//这个是策略B
public class BStrategy implements ICreateOrderAndMissionStrategy {
@Override
public Integer getType() {
return BizEnum.B.getCode(); }
/**
* B策略的实现逻辑
*/
@Override
public void doCreateOrderAndMission(ParamDTO paramDTO) {
.........
}
}
在真正的逻辑中,我们就可以直接使用这个模式了。
public class Demo{
public void Business(){
String[] taskTypeList = oscVo.getTaskTypes().split(",");
for (String i : taskTypeList) {
createHouseSourceOrderAndMission.executeStrategy(Integer.valueOf(i),oscVo);
}
}
}