策略模式-实际应用案例一

本文介绍了一个抽象策略类`AbstractCalcuateRuleValueStrategy`,该类用于根据不同的规则类型计算数据质量统计值。它涉及到波动率计算、规则实际值计算,并通过`RuleModelTypeFactory`工厂类来获取具体的策略实现。此外,还展示了`RuleModelTypeEnum`枚举类,用于定义不同类型的规则。具体策略实现类如`FieldAvgStrategy`实现了字段平均值的计算。这些组件共同工作,以实现灵活的数据质量管理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

抽象策略类:

AbstractCalcuateRuleValueStrategy.java
package cn.getech.data.manager.service.strategy;

import cn.getech.data.manager.constant.DayTypeEnum;
import cn.getech.data.manager.constant.RuleExpectedTypeEnum;
import cn.getech.data.manager.entity.DataQualityExcelDaily;
import cn.getech.data.manager.entity.DataQualityRuleDaily;
import cn.getech.data.manager.entity.DataQualityRulePartitionField;
import cn.getech.data.manager.model.dto.CalcuateRuleValueDto;
import cn.getech.data.manager.model.dto.RuleStatisticValueDto;
import cn.getech.data.manager.model.dto.TableStatisticValueDto;
import cn.getech.data.manager.model.vo.RuleDataRowVO;
import cn.getech.data.manager.model.vo.TableStatisticValueVO;
import cn.getech.data.manager.service.*;
import cn.getech.data.manager.service.factory.TableStatisticStrategyFactory;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.PageUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xxl.job.core.log.XxlJobLogger;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

public abstract class AbstractCalcuateRuleValueStrategy {

    @Autowired
    protected IDataQualityRuleService dataQualityRuleService;

    @Autowired
    private IDataQualityRuleDailyService dataQualityRuleDailyService;

    @Autowired
    private CalculateVolatilityService calculateVolatilityService;

    @Autowired
    private IDataQualityExcelDailyService  dataQualityExcelDailyService;

    @Autowired
    private IDataQualityRulePartitionFieldService dataQualityRulePartitionFieldService;


    /**
    * @Description 通过规则计算出实际值
    * @Author  chengweiping
    * @Date   2020/10/12 23:20
    */
    public final RuleStatisticValueDto calcuateValueByRule(CalcuateRuleValueDto calcuateRuleValueDTO){

        RuleStatisticValueDto ruleStatisticValueDto=new RuleStatisticValueDto();
        // 1:固定值 2:波动率
        Integer ruleExpectedType= calcuateRuleValueDTO.getRuleExpectedType();

        Integer connectId=calcuateRuleValueDTO.getConnectId();
        DataSourceStrategy dataSourceStrategy=dataQualityRuleService.getDataSourceStrategyByConnectId(connectId);

        //获取今天规则的统计值
        BigDecimal dayStatisValueDB= new BigDecimal(0);
        try {
            Long ruleId=calcuateRuleValueDTO.getRuleId();
            QueryWrapper queryWrapper=new QueryWrapper();
            queryWrapper.eq("rule_id",ruleId);
            //设置分区字段
            List<DataQualityRulePartitionField> partitionFieldList= dataQualityRulePartitionFieldService.list(queryWrapper);
            calcuateRuleValueDTO.setPartitionFieldList(partitionFieldList);
            //获取今天计算的统计值
            dayStatisValueDB = getTodayDayStatisValue(calcuateRuleValueDTO,dataSourceStrategy);
            XxlJobLogger.log("getTodayDayStatisValue,规则当前调用结果={}", JSON.toJSON(dayStatisValueDB));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {

            if(RuleExpectedTypeEnum.FIXED_VALUE.getCode().equals(ruleExpectedType)){
                ruleStatisticValueDto.setStatisticValue(dayStatisValueDB);
                ruleStatisticValueDto.setDayStatisticValuve(dayStatisValueDB);
            }else{
                //波动率计算
                LocalDate today=LocalDate.now();
                //之前的天数
                Integer dayType=   calcuateRuleValueDTO.getDayType();
                Integer day=0;
                //根据天数类型就是真实相差的天数
                if(dayType==null || DayTypeEnum.DAY.getCode().equals(dayType)){
                    day=calcuateRuleValueDTO.getDay();
                }else if(dayType==null || DayTypeEnum.MONTH.getCode().equals(dayType)){
                    day=calcuateRuleValueDTO.getDay()*DayTypeEnum.MONTH.getNum();
                }else if(dayType==null || DayTypeEnum.YEAR.getCode().equals(dayType)){
                    day=calcuateRuleValueDTO.getDay()*DayTypeEnum.YEAR.getNum();
                }else{
                    day=calcuateRuleValueDTO.getDay();
                }

                LocalDate beforeDay=today.minusDays(day);
                Long ruleId=calcuateRuleValueDTO.getRuleId();
                //获取今日的值
                DataQualityRuleDaily toDayQuality=new DataQualityRuleDaily();
                toDayQuality.setDayStatisticValue(dayStatisValueDB);
                //获取之前天数的值
                DataQualityRuleDaily  beforeQuality=dataQualityRuleDailyService.getByRuleIdAndDate(ruleId,beforeDay);
                //计算波动率
                BigDecimal statisValue=calculateVolatilityService.calculateVolatility(toDayQuality,beforeQuality);
                ruleStatisticValueDto.setStatisticValue(statisValue);
                ruleStatisticValueDto.setDayStatisticValuve(dayStatisValueDB);
            }

            //设置表的唯一率   空值率   重复值率   以及生成规则的excel数据
            //获取模板ID,如果是以下几种模板,要计算规则所在表对应规则的比率
            // 15:唯一值(固定)  19:空值(固定)  23:重复值(固定)
            String dbName=calcuateRuleValueDTO.getDataQualityInfo().getDatabaseName();
            String tableName=calcuateRuleValueDTO.getDataQualityInfo().getTableName();
            String fieldName=calcuateRuleValueDTO.getFieldName();
            Integer templateId=calcuateRuleValueDTO.getTemplateId();
            TableStatisticValueDto tableStatisticValueDto=new TableStatisticValueDto();
            tableStatisticValueDto.setConnectId(connectId);
            tableStatisticValueDto.setDbName(dbName);
            tableStatisticValueDto.setTableName(tableName);
            tableStatisticValueDto.setFieldName(fieldName);
            tableStatisticValueDto.setSqlWhere(calcuateRuleValueDTO.getSqlWhere());
            tableStatisticValueDto.setPartitionFieldList(calcuateRuleValueDTO.getPartitionFieldList());
            if(templateId!=null){
                AbstractTableStatisticStrategy  tableStatisticStrategy=TableStatisticStrategyFactory.getServiceByType(templateId);
                if(tableStatisticStrategy!=null){
                    TableStatisticValueVO tableStatisticValueVO= tableStatisticStrategy.calculateTableStatisticValue(tableStatisticValueDto);
                    ruleStatisticValueDto.setTableRuleRate(tableStatisticValueVO.getTableRuleRate());
                    ruleStatisticValueDto.setTableRuleRow(tableStatisticValueVO.getTableRuleRow());
                    ruleStatisticValueDto.setTableTotalRow(tableStatisticValueVO.getTableTotalRow());
                    //获取规则行数据
                    List<RuleDataRowVO> rowList=tableStatisticValueVO.getRowList();
                    //保存每日报表数据
                    saveExcelDailyData(rowList,calcuateRuleValueDTO.getQualityInfoId(),calcuateRuleValueDTO.getRuleId());
                }

            }



        } catch (Exception e) {
            e.printStackTrace();
        }
        return ruleStatisticValueDto;

    }

    /**
     * @Description
     * @Author  chengweiping
     * @Date   2020/10/20 16:17
     */
    private void saveExcelDailyData(List<RuleDataRowVO> rowList, Long qualityInfoId,Long ruleId){
        if(CollectionUtil.isEmpty(rowList)){
            return;
        }
        try{
            LocalDateTime nowDateTime= LocalDateTime.now();
            LocalDate nowDate=LocalDate.now();
            Map<String, Object> map=new HashMap<>();
            map.put("quality_info_id",qualityInfoId);
            map.put("rule_id",ruleId);
            map.put("statistic_date",nowDate);
            dataQualityExcelDailyService.removeByMap(map);
            List<DataQualityExcelDaily> resultList=rowList.stream().map(e->{
                DataQualityExcelDaily dataQualityExcelDaily=new DataQualityExcelDaily();
                dataQualityExcelDaily.setQualityInfoId(qualityInfoId);
                dataQualityExcelDaily.setRuleId(ruleId);
                dataQualityExcelDaily.setCreateTime(nowDateTime);
                dataQualityExcelDaily.setTableData(e.getTableData());
                dataQualityExcelDaily.setTableField(e.getTableField());
                dataQualityExcelDaily.setStatisticDate(nowDate);
                return dataQualityExcelDaily;
            }).collect(Collectors.toList());
            int totalPage = PageUtil.totalPage(resultList.size(), 100);
            for(int i=0;i<totalPage;i++){
                List subList=CollUtil.sub(resultList,i*100,(i+1)*100);
                dataQualityExcelDailyService.saveBatch(subList,100);
            }

        }catch (Exception e){
            e.printStackTrace();
        }

    }



    /**
     * @Description 校验模板规则,(试执行sql)
     * @Author  chengweiping
     * @Date   2020/10/12 23:20
     */
    public final BigDecimal verfiyTempalteRule(CalcuateRuleValueDto calcuateRuleValueDTO) throws  Exception{

        Integer connectId=calcuateRuleValueDTO.getConnectId();
        DataSourceStrategy dataSourceStrategy=dataQualityRuleService.getDataSourceStrategyByConnectId(connectId);
        BigDecimal dayStatisValueDB=null;
        try {
            Long ruleId=calcuateRuleValueDTO.getRuleId();
            QueryWrapper queryWrapper=new QueryWrapper();
            queryWrapper.eq("rule_id",ruleId);
            List<DataQualityRulePartitionField> partitionFieldList= dataQualityRulePartitionFieldService.list(queryWrapper);
            calcuateRuleValueDTO.setPartitionFieldList(partitionFieldList);
            //获取今天规则的统计值
            dayStatisValueDB=getTodayDayStatisValue(calcuateRuleValueDTO,dataSourceStrategy);

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return dayStatisValueDB;

    }


    /**
    * @Description 获取今天的统计值,每种规则的实现不一样,由子类实现
    * @Author  chengweiping
    * @Date   2020/10/14 14:43
    */
    public abstract BigDecimal getTodayDayStatisValue(CalcuateRuleValueDto calcuateRuleValueDTO, DataSourceStrategy dataSourceStrategy) throws Exception;



}

 

 策略工厂类:

RuleModelTypeFactory.java
package cn.getech.data.manager.service.factory;

import cn.getech.data.manager.service.strategy.AbstractCalcuateRuleValueStrategy;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName DataSourceStrategyFactory
 * @Description   表明服务工厂
 * @Author Getech
 * @Date 2020/10/10 14:06
 */
public class RuleModelTypeFactory {

    private static ConcurrentHashMap<Integer, AbstractCalcuateRuleValueStrategy>  serviceMap=new ConcurrentHashMap<>();




    public static AbstractCalcuateRuleValueStrategy getServiceByType(Integer ruleModel){
        return serviceMap.get(ruleModel);
    }

    public static void setService(Integer ruleModel, AbstractCalcuateRuleValueStrategy strategy){
            serviceMap.put(ruleModel, strategy);
    }
}

 

枚举类:

RuleModelTypeEnum.java
package cn.getech.data.manager.constant;

/**
 * @ClassName DataSourceTypeEnum
 * @Description TODO
 * @Author Getech
 * @Date 2020/10/10 14:22
 */
public enum RuleModelTypeEnum {

    /**
     * 1:表行数 2:表大小  3:字段平均值 4:字段汇总值  5:字段最大值
     * 6 字段最小值  7: 字段唯一值 8: 字段空值  9:字段重复值
     */


    TABLE_ROW(1,"表行数"),

    TABLE_SIZE(2,"表大小"),

    FIELD_AVG(3,"字段平均值"),

    FIELD_SUM(4,"字段汇总值"),

    FIELD_MAX(5,"字段最大值"),

    FIELD_MIN(6,"字段最小值"),

    FIELD_UNIQUE(7,"字段唯一值"),

    FIELD_NULL(8,"字段空值"),

    FIELD_REPEAT(9,"字段重复值"),

    LIB_TEMPLATE(100,"模板库规则自定义类型");

    private Integer ruleModel;

    private String name;

    RuleModelTypeEnum(Integer ruleModel, String name) {
        this.ruleModel = ruleModel;
        this.name = name;
    }

    public Integer getRuleModel() {
        return ruleModel;
    }

    public void setRuleModel(Integer ruleModel) {
        this.ruleModel = ruleModel;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }}

 

具体策略实现类:

FieldAvgStrategy.java
package cn.getech.data.manager.service.strategy.impl;

import cn.getech.data.manager.constant.RuleModelTypeEnum;
import cn.getech.data.manager.model.dto.CalcuateRuleValueDto;
import cn.getech.data.manager.model.dto.QueryDto;
import cn.getech.data.manager.model.dto.RuleStatisticValueDto;
import cn.getech.data.manager.service.IDataQualityRuleService;
import cn.getech.data.manager.service.factory.RuleModelTypeFactory;
import cn.getech.data.manager.service.strategy.AbstractCalcuateRuleValueStrategy;
import cn.getech.data.manager.service.strategy.DataSourceStrategy;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * @ClassName TableRowStrategyAbstract
 * @Description 字段平均值策略
 * @Author Getech
 * @Date 2020/10/12 23:32
 */
@Service
public class FieldAvgStrategy extends AbstractCalcuateRuleValueStrategy implements InitializingBean {

    @Autowired
    private IDataQualityRuleService dataQualityRuleService;

    @Override
    public void afterPropertiesSet() throws Exception {
        RuleModelTypeFactory.setService(RuleModelTypeEnum.FIELD_AVG.getRuleModel(),this);
    }

    @Override
    public BigDecimal getTodayDayStatisValue(CalcuateRuleValueDto calcuateRuleValueDTO, DataSourceStrategy dataSourceStrategy) throws Exception {
        Integer connectId=calcuateRuleValueDTO.getDataQualityInfo().getConnectId();
        RuleStatisticValueDto ruleStatisticValueDto=new RuleStatisticValueDto();
        BigDecimal bd=null;
        try {
            String dbName=calcuateRuleValueDTO.getDataQualityInfo().getDatabaseName();
            String tableName=calcuateRuleValueDTO.getDataQualityInfo().getTableName();
            String fieldName=calcuateRuleValueDTO.getFieldName();
            QueryDto queryDto=new QueryDto();
            queryDto.setConnectId(connectId);
            queryDto.setDbName(dbName);
            queryDto.setTableName(tableName);
            queryDto.setFieldName(fieldName);
            queryDto.setSqlWhere(calcuateRuleValueDTO.getSqlWhere());
            queryDto.setPartitionFieldList(calcuateRuleValueDTO.getPartitionFieldList());
            bd = dataSourceStrategy.getFieldAvgNum(queryDto);
            ruleStatisticValueDto.setStatisticValue(bd);
            ruleStatisticValueDto.setDayStatisticValuve(bd);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return bd;
    }
}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

成伟平2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值