规则引擎常作为一个独立服务运行在一定体量的产品之中,通过接收有效的数据来做出对业务的合理决策。在前端项目的常年迭代下,对于某些重要的或频繁扩展改造的业务模块由于时间长、注释少、不易阅读等客观问题的遗留会对后期的迭代造成一定困扰,也不免会造成额外的测试压力。所以轻量的、可运行在浏览器端得规则引擎将彻底消灭这样问题的存在。
适用于浏览器端的规则引擎在开源社区已有实现,这里我们就通过开源项目来走进规则引擎的世界~
json-rules-engine is a powerful, lightweight rules engine. Rules are composed of simple json structures, making them human readable and easy to persist.
由 JSON 数据格式来组合规则,这样既便于规则的阅读也便于规则的持久化存储,还有轻量也是它的特点之一~
2.1 制定游戏规则:
在某一运动赛事规则的制定时共同约定:
- 当比赛进行到 40 分钟时,如果运行员犯规次数达到 5 次及以上的因被罚出场;
- 当比赛进行到 48 分钟时,如果运动员犯规次数达到 6 次及以上的因被罚出场;
2.2 搭建规则引擎:
2.2.1 创建引擎:
通过简单的模块导入并实例化引擎对象即完成了引擎的创建工作:
2.2.2 添加规则:
通过对象来定义当规则被命中后所触发的信息,通过对象来定义具体的规则,每个规则至少包含、、三部分,分别定义事实名称、操作符和当前规则的阈值或范围,规则和规则之间使用 来表示逻辑或和使用 来表示逻辑与的关系,这样就组成了这次赛事的具体规则:
2.2.3 定义Facts:
这里使用对象来表示一个Fact,让它进入到规则引擎并经过每一条规则来判断是否允许通过:
2.2.4 运行引擎:
通过引擎校验后将在控制台输出的信息,说明这个运动员已经命中了被罚出场的规则~
3.1 场景 1&多属性控制菜单:
在线上项目的某一个菜单处出现了同时由 8 个属性共同控制一个菜单的显示与隐藏,猜想在最初也只是仅包含一个用户权限和数据状态的控制吧,但随着业务的持续变动导致这块的控制属性持续增加,也是在最近的迭代中又为这个菜单补充了一个属性的控制,其实这些属性中也不全是 Boolean 类型的判断,下面通过对比源代码和应用规则引擎后的代码来看一下:
3.2 场景 2&多属性多分支控制菜单:
上面的场景 1 你可能看不出来规则引擎带来的便利,可能觉得原来的代码看起来也说的过去,那接着看这个包含多个分支的控制案例。
商户开票的功能设计由于不同的开票方式等其他的一系列因素导致这块有 4 个比较大的分支处理,这里我拆分出其中的一个分支来利用规则引擎简单的实现一下:
3.2.1 源项目逻辑分析:
下面是摘自源项目的部分逻辑控制,其中部分的属性和函数背后还有很多的逻辑处理,对于代码的阅读和功能的测试都会造成困扰:
3.2.2 引擎规则编写:
通过源代码分析控制此菜单的数据达 10 个,通过逻辑与和逻辑或共同控制着 16 条规则的运行:
3.2.3 规则示意图:
规则可视化的前提就需要将编写的引擎规则转为 JSON 对象,通过加载 JSON 对象实现规则的可视化工作。
4.1 规则 JSON 化处理:
模块中的 对象提供了函数,我们直接编写脚本来得到一份 json 化后的规则数据:
在得到规则数据后需要对数据做简易处理,通过来命名这个规则的名称以示区分,在中插入得到的规则数据: