结合Spring实现策略模式
最近系统需要对不同维度的数据进行差异化计算,也就会使用不同算法。为了以后更加容易扩展,结合Spring框架及策略模式对实现架构做了系统设计。
1. 定义策略接口(Strategy):
import com.dmall.scfc.biz.dao.model.ScfcScoreField; import com.dmall.scfc.biz.dao.model.ScfcScoreFieldValue; import com.dmall.scfc.biz.dto.ScoreModelDimensionDTO; import java.util.List; /** * @author wangxuexing * @descrption 数据抽取策略 * @date 2019/12/4 */ public interface Strategy { /** * 是否匹配策略 * @param scoreField 基础字段 * @return */ boolean isMatch(ScfcScoreField scoreField); /** * 根据具体字段抽取数据 * @param dimensionRule * @return */ List<ScfcScoreFieldValue> extractData(ScoreModelDimensionDTO dimensionRule) throws Exception; }
2. 实现具体策略
import java.util.List; /** * @author wangxuexing * @descrption scf-score 基础维度表按模型设置日期聚合策略 * @date 2019/12/4 */ @Service public class BaseBySettingStrategy implements Strategy { @Autowired private ScfcScoreFieldValueService scoreFieldValueService; @Override public boolean isMatch(ScfcScoreField scoreField) { return ProcessFlagEnum.BASE_BY_SETTING.getCode() == scoreField.getProcessFlag(); } @Override public List<ScfcScoreFieldValue> extractData(ScoreModelDimensionDTO dimensionRule) throws Exception { return scoreFieldValueService.getBaseFieldValueByDimension(dimensionRule); } }
可以继续往后继续实现多个算法,这里就不一一列举。
3. Spring Boot启动时初始化各算法
import com.dmall.scfc.task.strategy.Strategy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @author wangxuexing * @descrption 加载所有抽取策略 * @date 2019/12/4 */ @Configuration public class ExtractStrategyConfig { @Autowired private ApplicationContext applicationContext; @Bean public List<Strategy> pipelineProcessors() { Map<String, Strategy> beansOfType = applicationContext.getBeansOfType(Strategy.class); List<Strategy> strategies = new ArrayList<Strategy>(); for (Strategy processService : beansOfType.values()) { strategies.add(processService); } return strategies; } }
4. 基于业务场景对不同策略经行调用
import com.dmall.dispatcher.sdk.util.IBasicExecuteContext; /** * @author wangxuexing * @descrption 数据抽取服务 * @date 2019/12/4 */ public interface DataExtractService { /** * 根据具体字段抽取数据 */ void extractData(); }
/** * @author wangxuexing * @descrption 上下文调用各策略 * @date 2019/12/4 */ @Slf4j @Service public class DataExtractServiceImpl implements DataExtractService { @Autowired private List<Strategy> strategyList; /** * 根据具体字段抽取数据 */ @Override public void extractData() { //查询所有核心企业,所有维度公式及条件 List<ScoreModelDimensionDTO> scoreModelDimensionDTOS = scfcScoreModelDimensionService.getAllScoreModelDimensions(); scoreModelDimensionDTOS.forEach(item -> { //执行不同满足匹配条件的策略 strategyList.forEach(strategy -> { extractAndInsertDataByStrategy(strategy, item); }); }); } /** * 根据策略抽取数据并插入 */ @Async//多线程异步计算插入数据 private void extractAndInsertDataByStrategy(Strategy strategy, ScoreModelDimensionDTO dimensionRule){ try{ List<Long> fieldIds = scoreFields.stream() .filter(scoreField -> strategy.isMatch(scoreField)) .map(x->x.getId()) .collect(Collectors.toList()); if(CollectionUtils.isNotEmpty(fieldIds)) { dimensionRule.setScoreRuleIds(fieldIds); //根据策略抽取数据 List<ScfcScoreFieldValue> resultList = strategy.extractData(dimensionRule); if(CollectionUtils.isNotEmpty(resultList)) { //设置维度ID及抓取时间 scoreFieldValueService.insertScoreFieldValueBatch(resultList); } } } catch (Exception e) { log.error("根据策略"+strategy.getClass().getName()+"抽取数据失败", e); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决