最近系统需要对不同维度的数据进行差异化计算,也就会使用不同算法。为了以后更加容易扩展,结合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);
}
}
}

结合Spring实现策略模式的更多相关文章

  1. Spring 实现策略模式--自定义注解方式解耦if...else

    策略模式 定义 定义一簇算法类,将每个算法分别封装起来,让他们可以互相替换,策略模式可以使算法的变化独立于使用它们的客户端 场景 使用策略模式,可以避免冗长的if-else 或 switch分支判断 ...

  2. 基于Spring实现策略模式

    背景: 看多很多策略模式,总结下来实现原理大体都差不多,在这里主要是讲解下自己基于Spring更优雅的实现方案:这个方案主要是看了一些开源rpc和Spring相关源码后的一些思路,所以在此进行总结 首 ...

  3. 策略模式、策略模式与Spring的碰撞

    策略模式是GoF23种设计模式中比较简单的了,也是常用的设计模式之一,今天我们就来看看策略模式. 实际案例 我工作第三年的时候,重构旅游路线的机票查询模块,旅游路线分为四种情况: 如果A地-B地往返都 ...

  4. Spring设计模式_策略模式/其他

    策略模式特性 1.执行最终结果一样 2.执行过程和执行逻辑不一样 3.使用同一接口 达到目的就可以了 Git地址 https://github.com/wujiachengSH/WjcStrategy ...

  5. 设计模式_策略模式_在Spring中的应用

    一.理论 在spring中经常有读取配置文件的需求,这里就会用到一个Spring提供的Resource接口 Resource 接口是具体资源访问策略的抽象,也是所有资源访问类所实现的接口.Resour ...

  6. 在商城系统中使用设计模式----策略模式之在spring中使用策略模式

    1.前言: 这是策略模式在spring中的使用,对策略模式不了解对同学可以移步在商城中简单对使用策略模式. 2.问题: 在策略模式中,我们创建表示各种策略的对象和一个行为,随着策略对象改变而改变的 c ...

  7. 【Spring源码解析】—— 策略模式在Spring中的应用

    一.         什么是策略模式 策略模式的定义/含义:策略本身就是为了实现某一个目标而采取的一种工作方式,因此只要能够达成目标,则采取哪一种策略都可以:因此多种实际的策略之间是相互平行的. 注意 ...

  8. 如何在Spring Boot项目中巧妙利用策略模式干掉if else!

    直入主题 我们都知道,设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性.稳健性以及安全性 ...

  9. Spring中常见的设计模式——策略模式

    策略模式(Strategy Pattern) 一.策略模式的应用场景 策略模式的应用场景如下: 系统中有很多类,而他们的区别仅仅在于行为不同. 一个系统需要动态的在集中算法中选择一种 二.用策略模式实 ...

随机推荐

  1. 小记 .NET Core 3.0 下 WPF 是如何运行的

    1. 解决方案架构 如图: 2. 生成的代码 如图: /// <summary> /// App /// </summary> public partial class App ...

  2. Pandas 学习 第9篇:DataFrame - 数据的输入输出

    常用的数据存储介质是数据库和csv文件,pandas模块包含了相应的API对数据进行输入和输出: 对于格式化的平面文件:read_table() 对于csv文件:read_csv().to_csv() ...

  3. LOOP AT GROUP语法练习

    DATA:P_MENGE TYPE EKKO-WKURS. DATA:P_MENGE1 TYPE EKKO-WKURS. SELECT * FROM EKKO INTO TABLE @DATA(LT_ ...

  4. Java自学-集合框架 ArrayList常用方法

    ArrayList常用方法 步骤 1 : 增加 add 有两种用法: 第一种是直接add对象,把对象加在最后面 heros.add(new Hero("hero " + i)); ...

  5. Linux之Shell编程(15)

    case: for:   while:

  6. 学习shiro第三天

    今天比较晚,所以只看了shiro的认证策略Authentication Strategy,下面讲讲shiro的三种认证策略. 1.AtLeastOneSuccessfulStrategy:这个是shi ...

  7. odoo12 如何设置超级用户

    在odoo12的版本中,和之前的版本有点不一样的地方 在odoo12版本之前,每个实例都是使用户名为Administrator的默认用户来创建的. 在数据库中user_id是1. 在代码中,你会发现 ...

  8. 3-6 merge操作

    In [1]: import pandas as pd In [6]: left =pd.DataFrame({ 'A':['A0','A1','A2','A3'], 'B':['B0','B1',' ...

  9. java XML解析防止外部实体注入

    /** * 增加防止部实体注入逻辑 * <功能详细描述> * @param reader * @throws SAXException * @see [类.类#方法.类#成员] */ pu ...

  10. 5.1 RDD编程

    一.RDD编程基础 1.创建 spark采用textFile()方法来从文件系统中加载数据创建RDD,该方法把文件的URL作为参数,这个URL可以是: 本地文件系统的地址 分布式文件系统HDFS的地址 ...