复杂业务规则配置如何告别IF ELSE?如何更加优雅的实现优先级配置获取?

背景

复杂业务配置场景,如何取值?

  1. 获取满足条件的所有配置?
  2. 获取优先级最高的配置?

你该如何实现?

产品型号产品分类地区需求日期配置
ABC(1-20]配置1
AC(1-20]配置2
AB配置3
C(1-20]配置4
AC(30-40]配置5

那如果维度新增一列,该怎么办呢?

工具介绍

业务工具集,为解决复杂的业务规则和业务配置,提供一种工具类解决方案,提高开发效率和代码可读性

如何使用:Maven引入

<dependency>
    <groupId>cn.ykccchen</groupId>
    <artifactId>business-util</artifactId>
    <version>1.0.1</version>
</dependency>

使用说明

  1. 创建优先级匹配规则
PriorityAssembler<Source, Config, Key> assembler = PriorityAssembler.from(Source.class, Config.class, Key.class);
  1. 初始化配置,将配置进行加载
assembler.initConfig(configList);
  1. 添加匹配规则
//默认为相等的匹配规则
assembler.addPriorityMatchFunction("规则名称", source -> source.getKey(), config -> config.getKey());

//如果是正则或者区间匹配,可以使用boolean匹配模式
priorityAssembler.addPriorityMatchFunction("规则名称" , source -> source.getKey(), config -> config.getKey() , (source, config) -> {
            if (config instanceof Range && source instanceof Integer) {
                Range<Integer> range = (Range) config;
                return range.contains((Integer) source);
            }
            return false;
        })
  1. 设置优先级处理器模式,可以自定义,内置2种模式,不选择默认 PriorityMode.NUMBER_OF_MATCHES
/**
 * 配置值数量优先
 * PriorityMode.NUMBER_OF_MATCHES 
 * A B C D 4个配置维度
 * A C D 优先级大于 A B
 * A B C  优先级大于 A B D
 * 3个维度一定大于2个维度
 */
assembler.initPriorityHandler(PriorityMode.NUMBER_OF_MATCHES);
/**
  * 绝对值优先
  * A B C D 4个配置维度
  * A B  优先级大于 A C D
  * A B C  优先级大于 A B
  * A B C  优先级大于 A B D
  * 绝对价值维度
  */
assembler.initPriorityHandler(PriorityMode.ABSOLUTE_VALUE);

  1. 创建优先级获取器
//默认会做剪枝,删除不存在的优先级校验项
PriorityFetcher<Source, Config, Key> fetcher = assembler.create();
// 优先级匹配初始化后可以转换为树,非必须项,当存在叶子节点数据 >= 8 时,才比较有性价比, priorityFetcher.getProcessorList() >= 8
PriorityFetcher<Map<String, Serializable>, Map<String, Serializable>, Serializable> priorityFetcher = priorityAssembler.create().tree();
  1. 执行匹配
// 获取优先级最高的配置
PriorityMatchResult<List<Config>> result = fetcher.match(source);
// 获取全部能匹配的数据,集合顺序为优先级顺序
List<PriorityMatchResult<List<Map<String, Serializable>>>> resultList = fetcher.match(source, true);

简单demo

    // 这里使用有序的哈希MAP, 保证优先级的顺序的对的,这个逻辑必须
    List<Function<Map<String, Serializable>, Serializable>> mapByValue = new ArrayList<>();
    // key值为维度的获取方式, value值为价值,值越高价值越大
    mapByValue.add(map -> map.get("p1"));
    mapByValue.add(map -> map.get("p2"));
    mapByValue.add(map -> map.get("p3"));
    mapByValue.add(map -> map.get("p4"));
    //初始化配置优先级组合集
    PriorityAssembler<Map<String, Serializable>, Map<String, Serializable>, Serializable> priorityAssembler = PriorityAssembler.from(new PriorityAssembler.TypeReference<Map<String, Serializable>>() {
            }, new PriorityAssembler.TypeReference<Map<String, Serializable>>() {
            }, new PriorityAssembler.TypeReference<Serializable>() {
            })
            .initConfig(new ArrayList())
            .initPriorityHandler(PriorityMode.ABSOLUTE_VALUE);
    //初始化数据获取逻辑
    for (int i = 0; i < mapByValue.size()-1; i++) {
        priorityAssembler.addPriorityMatchFunction("配置"+ (i+1), mapByValue.get(i), mapByValue.get(i));
    }
    priorityAssembler.addPriorityMatchFunction("配置"+ 4, mapByValue.get(3), mapByValue.get(3), (source, config) -> {
        if (config instanceof Range && source instanceof Integer) {
            Range<Integer> range = (Range) config;
            return range.contains((Integer) source);
        }
        return false;
    });


    // 创建对象
    PriorityFetcher<Map<String, Serializable>, Map<String, Serializable>, Serializable> priorityFetcher = priorityAssembler.create().tree();

    // 匹配
    for (Map<String, Serializable> req : new ArrayList()) {
        PriorityMatchResult<List<Map<String, Serializable>>> match = priorityFetcher.match(req);
        if (match != null) {
            System.out.println("需求:" + req.toString() + ", 配置:" + match.toString() +",配置值:"+match.getResult());
        } else {
            System.out.println("需求:" + req.toString() + "未命中配置");
        }
    }

gitee地址:https://gitee.com/xiaokuntt/business-util
github地址:https://github.com/xiaokuntt/business-util

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值