zoukankan      html  css  js  c++  java
  • 结合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);
            }
        }
    }
  • 相关阅读:
    could not load file or assembly "System.Web.Mvc...
    .Net利用cwbx.dll call AS400 program得到数据
    fastadmin 如何构建组合题--Cannot read property '0' of undefined
    fastadmin的前端js文件中api和event的区别,formatter的意思
    fastadmin是如何使用art-template的,以及如何在js模板中,嵌套JS模板
    学习fastadmin的新技巧:去git里面看文件的修改
    thinphp5,模型调用模型,和控制器调用模型的区别
    fa使用技巧+tp5技巧总结
    input autocomplete的作用是什么?
    fastadmin 实现标签的多选研究---基于fa的test案例,已经CMS中的标签写法
  • 原文地址:https://www.cnblogs.com/barrywxx/p/12003517.html
Copyright © 2011-2022 走看看