背景
复杂业务配置场景,如何取值?
- 获取满足条件的所有配置?
- 获取优先级最高的配置?
你该如何实现?
产品型号 | 产品分类 | 地区 | 需求日期 | 配置 |
---|---|---|---|---|
A | B | C | (1-20] | 配置1 |
A | C | (1-20] | 配置2 | |
A | B | 配置3 | ||
C | (1-20] | 配置4 | ||
A | C | (30-40] | 配置5 |
那如果维度新增一列,该怎么办呢?
工具介绍
业务工具集,为解决复杂的业务规则和业务配置,提供一种工具类解决方案,提高开发效率和代码可读性
如何使用:Maven引入
<dependency>
<groupId>cn.ykccchen</groupId>
<artifactId>business-util</artifactId>
<version>1.0.1</version>
</dependency>
使用说明
- 创建优先级匹配规则
PriorityAssembler<Source, Config, Key> assembler = PriorityAssembler.from(Source.class, Config.class, Key.class);
- 初始化配置,将配置进行加载
assembler.initConfig(configList);
- 添加匹配规则
//默认为相等的匹配规则
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;
})
- 设置优先级处理器模式,可以自定义,内置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);
- 创建优先级获取器
//默认会做剪枝,删除不存在的优先级校验项
PriorityFetcher<Source, Config, Key> fetcher = assembler.create();
// 优先级匹配初始化后可以转换为树,非必须项,当存在叶子节点数据 >= 8 时,才比较有性价比, priorityFetcher.getProcessorList() >= 8
PriorityFetcher<Map<String, Serializable>, Map<String, Serializable>, Serializable> priorityFetcher = priorityAssembler.create().tree();
- 执行匹配
// 获取优先级最高的配置
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