Spring Boot项目中使用策略模式
2019-08-27 本文已影响0人
浅笑丨无痕
Spring Boot项目中使用策略模式
最近负责一个功能,需要根据不同模式算出不同结果。一开始为了简便,直接用一坨if-else来区分,以下是简化的代码
if (Objects.isNull(forecastType)) {
// 默认类型
...
} else if (ForecastTypeEnum.MLFUNC_FORECAST.getKey().equals(forecastType)) {
//算法分析
...
} else if (ForecastTypeEnum.HISTORY_AVG.getKey().equals(forecastType)) {
//历史均价
...
} else if (ForecastTypeEnum.SIMULATE_DATA.getKey().equals(forecastType)) {
//仿真数据
...
} else if (ForecastTypeEnum.HISTORY_SIMILAR.getKey().equals(forecastType)) {
//历史相似日
...
}
开发完后开始对代码优化,想到之前学过策略模式,刚好符合场景,于是开始改造。
1.定义一个策略接口
public interface IPriceStrategy {
/**
* 处理数据
* @param QueryReq
*/
Resp handle(QueryReq queryReq);
}
2. 实现类
类实现步骤1的接口
/**
* 算法预测处理
*/
@Component(CommonConst.PREFIX_PRICE_STRATEGY + "4")
public class MlFunTypeHandle implements IPriceStrategy {
@Override
public Resp handle(QueryReq queryReq) {
//具体实现
}
}
/**
* 默认处理
*/
@Component(CommonConst.PREFIX_PRICE_STRATEGY + "0")
public class DefaultHandle implements IPriceStrategy {
@Override
public Resp handle(QueryReq queryReq) {
//具体实现
}
}
/**
* 历史均价处理
*/
@Component(CommonConst.PREFIX_PRICE_STRATEGY + "3")
public class HistoryAvgTypeHandle implements IPriceStrategy {
@Pluginwired
private IBaseDataPlugin baseDataPlugin;
@Override
public Resp handle(QueryReq queryReq) {
//具体实现
}
}
这里就不全列出来了。
3.构建一个上下文
@Service
public class PriceStrategyContext {
@Autowired
private final Map<String, IPriceStrategy> priceStrategyMap = new ConcurrentHashMap<>();
public PriceStrategyContext(Map<String, IPriceStrategy> priceStrategyMap) {
this.priceStrategyMap.clear();
priceStrategyMap.forEach(this.priceStrategyMap::put);
}
public IPriceStrategy getStrategy(String strategy){
return priceStrategyMap.get(strategy);
}
}
4.使用
public class ServiceImpl implements Service {
@Autowired
private PriceStrategyContext priceStrategyContext;
@Override
public DailyDeclareResp getByParams(QueryReq queryReq) {
IPriceStrategy priceStrategy = Optional.ofNullable(priceStrategyContext.getStrategy(CommonConst.PREFIX_PRICE_STRATEGY + queryReq.getType())).orElseThrow(() -> new BusinessException("没有找到相关的策略"));
return priceStrategy.handle(entityId,priceQueryReq);
}
}
注入步骤3的上下文,然后直接根据类型获取即可。