个人博客: 无奈何杨(wnhyang)
个人语雀: wnhyang
共享语雀: 在线知识共享
Github: wnhyang - Overview
参考
< https://juejin.cn/post/7005869798483558431>
< https://gitee.com/freshday/radar/wikis/home>
条件配置
在需要灵活配置规则的业务系统中,如上图这样的条件配置非常常见。
不管是在第一个参考链接(< https://juejin.cn/post/7005869798483558431>)里或是从自己的分析中都可以知道条件配置就是对同一逻辑单元的与或非编排。对于LiteFlow
相同组件的编排有组件标签和组件参数两种解决方法。
组件标签实现
通过组件标签实现,就是在编排LiteFlow
时加上组件tag
。
那么就将条件存储在数据库中,在组件运行时通过tag
再到数据库中去取。
id | type | value | logic_type | expect_type | expect_value |
1 | normal | N_S_appName | eq | input | phone |
2 | normal | N_S_payerAccount | eq | input | 123456 |
3 | normal | N_F_transAmount | gt | input | 15 |
4 | normal | N_S_appName | eq | input | phone |
5 | normal | N_F_transAmount | lt | input | 100 |
6 | normal | N_F_transAmount | gte | input | 20.0 |
7 | normal | N_S_appName | eq | context | N_S_ipCity |
8 | zb | 1 | gt | input | 20 |
如:IF(AND(c_cn.tag("4"),c_cn.tag("5")),r_tcn.tag("2"),r_fcn);
就是对条件组件c_cn.tag("id")
进行与或非编排,就能几乎适用于所有条件。
忽略公共字段,实际上有用的只有type
、value
、logicType
、expect_type
、expect_value
。
与type
相对,value
代表的意义不同,type
为normal
时,value
是系统字段名;为zb
时,value
是指标id
,等等,可参考以下组件示例代码。
logicType
取值如上,同样,根据type
和value
的不同,逻辑适用的也不同,具体不同参考以下普通字段类型和逻辑函数式接口的实现。
expectType
有上,同样适用于不同条件。
字段
字段命名规则为[N/D]_[S/N/F/D/E/B]_{name}
。
N
普通字段,D
动态字段;S/N/F/D/E/B
字段类型;name
字段名。
如:N_S_appName
表示普通字符字段appName
;N_D_transTime
表示普通日期字段transTime
。
逻辑运算
逻辑运算实现有下。
这样做是为了简化条件组件代码,抽象一些实现。
条件组件|组件标签
组件参数实现
组件参数与组件标签不同,数据就存储在EL
表达式中。
与上面组件标签表达式IF(AND(c_cn.tag("4"),c_cn.tag("5")),r_tcn.tag("2"),r_fcn);
对应的组件参数表达式是:
这样在条件组件中就不用再通过tag再次查询数据库来获取数据了。
如上的组件标签组件实现替换为以下方法就好。
而且对于这样的条件配置几乎不会复用,都是配置即存在删除即无,省去了删除条件配置同时要在数据库中删除多条条件数据的繁琐步骤。对于其缺点,可能就是在需要反向查找时,有点麻烦。因为绝大多数时候都是使用条件配置确认最终的条件,但是如果反向要查找某字段、指标、名单集被引用的地方,就比较麻烦了,这就需要从Chain
解析到所有条件,然后再判断,不如数据库中直接能找到引用的。
EL与或非表达式与条件json的正反向解析
上面都是关于后端条件数据存储的一点想法,但其最终到前端都是要成为统一的结构化数据的。
配置的规则条件总要反显到前端吧,前端条件json
总要送给后端用于组成EL
表达式吧。
如果有这样的条件类,其中logicOp
取值有AND|OR|NOT
,其与children
共生共存,与其他条件字段互斥,即logicOp
和children
要么都有值要么都为空,当其有值时其他条件字段为空,当其为空时,其他一定有值,表示具体的逻辑条件。
还有一点要注意AND
和OR
是接受复合子条件的,而NOT
仅支持单个子条件。
在以下示例中并不完善,使用仅是字符串的处理,大家可以尝试一下ElBus
的构建,而且没有正确性校验,仅供参考。
其提供了条件类到EL
表达式的构建和EL
表达式反向解析到类的方法。
测试结果
元数据管理
在v2.12.0
中加入的元数据管理,可以通过FlowBus
获取Chain
和Node
的信息。
如下面这样的chain
,可以通过FlowBus.getChain
和FlowBus.getNodesByChainId
分别获取Chain
和Chain
对应的组件Node
。
测试Debug
一下。
Chain
的所有信息都是有的,不过这个就要求对于LiteFlow
的Chain
和Node
设计理解比较深了。
相比于直接获取Chain
,获取Node
看起来就简单多了,尤其对于我们在文档中常见的组件标签和组件参数,一览无遗。
总结
最后总结一下组件标签和组件参数在以上应用中所带来的差别,简称方式1和2了,下面👇
其实其带来的差别只有方式1
多了一张条件表,所以差别就在这里,废话🤪
对于创建EL
:方式1
需要多创建一条数据,方式2
就避免这样的麻烦,直接放在EL
就好了。
对于更新EL
:如果当作全新的条件,方式1
要先删除原有条件,再插入新的条件;如果要对比新老后再修改,那方式1
就更麻烦了。而对于方式2
,不管是怎样,直接覆盖就好了。
对于删除EL
:方式1
需要删除所有的条件数据,方式2
就不会有这些烦恼。
对于运行组件:方式1
需要多查一步数据库,方式2
更简单了使用获取组件方法就好,而且支持直接转类型,很方便。
从上面对比来看方式2
爆杀啊!但还没对比完呢!
当需要反向查找时,方式2
就有劣势了。反向查找指的是需要查询上面设计条件里的字段、指标、名单集的引用时,方式1
可以方便的直接到数据库层查找引用的EL
,而方式2
就漫无目的了,不经其他设计的话,只能全部EL
遍历了。
写在最后
拙作艰辛,字句心血,望诸君垂青,多予支持,不胜感激。
个人博客: 无奈何杨(wnhyang)
个人语雀: wnhyang
共享语雀: 在线知识共享
Github: wnhyang - Overview