Loading... # 业务规则引擎(Business Rule Engine) ## **什么是规则引擎** 在实际的业务场景中, 会有多个业务规则, 这些政策可能是公司策略, 也可能是法律法规要求. 例如在注册新用户时, 如果年龄小于18岁则需要同意额外的用户协议, 或者在促销时, 满足一定的金额要求则进行部分费用减免. 这些都是业务规则, 而基于这些规则, 给定一个或多个事实, 事实满足规则后可执行一些动作, 这便是规则引擎. 简单来说,你可以看成一堆 `if-else` 语句. 基本上, 规则引擎围绕以下几个点进行操作: * 规则(Rule), 即是条件. * 事实(Fact), 存在某种东西是一种事实, 不存在某种东西也是一种事实, 规则引擎将现有的事实带入到规则中, 如果满足则执行动作. * 动作(Action), 满足某种规则后需要执行的动作. ## **为什么需要规则引擎** 主要有以下几个原因: * 业务规则是多变的. 例如今天可能针对22岁以下的用户给予学生优惠, 明天则可能只针对18岁以下的用户给予学生优惠. 你肯定不想天天改这部分代码. * 业务规则具有种类多的特点. 例如满100元减免50元. 满200元减免110元. 满300元打1折 等等等等很多种规则, 如果将这部分逻辑硬写到代码里, 会有大量的条件判断, 且难以维护. 并且业务反复更改时, 都需要反复变更这部分代码. * 需要满足时效性要求. 规则硬编码到程序内部意味着规则的更改需要编码和部署, 整个上线流程是需要花费时间的, 如果能够在业务规则发生变化时, 动态重新加载规则, 甚至无需重新部署则新的规则便可应用, 那就极大的减少了变更规则带来的时间成本. * 让运营人员自己可动态配置规则. 这是很多人使用规则引擎所期望的一件事情, 让运营自己管理业务规则, 不占用开发资源. 但是与往常一样,这听起来似乎有道理,但在实践中却很少行得通. 要满足这个要求, 大部分情况下需要对规则引擎进行二次开发, 否则最终结果很可能便是配置了一堆没有人知道是干什么的规则. ## **业务场景** * 优惠券 * 满减 * 折扣 * 指定商品扣减 * 立减 * 活动 * 全场七折 * 某个日期范围内立减 * 某个品牌七折 * 女用户七折 如果现在有如上促销活动逻辑, 你应该怎么做? 将所有的业务逻辑硬编码到代码里? 哼哧哼哧开干, 刚完工, 这时候业务运营大佬来了: `不行啊, 全场七折要亏死了, 得改成全场9折, 另外这个某品牌七折活动他们突然不合作了, 得拿掉这个规则`. 那么今天你和运营大佬可能只有一个人能站着走出去. 但是, 如果你用了规则引擎, 则可以泰然自若, 喝一口浓茶并花一分钟修改和禁用规则. ## **Drools** [Drools](https://www.drools.org/)是[KIE(Knowlegde is Everything)](https://www.kie.org/)社区的产物, 专门用来做业务规则引擎, 具有基于前向链和后向链推理的规则引擎,可以快速可靠地评估业务规则和复杂事件处理, 还可以与[jBMP](https://www.jbpm.org/)进行业务流程处理上的配合. ### **运行原理** * `Drools`引擎使用以下基本组件运行 * 规则(Rules): 业务规则, 所有规则必须至少包含触发规则的条件和规则规定的操作. * 事实(Facts): 在`Drools`引擎中输入或更改的数据, 与规则条件匹配以执行适用的规则. * 生产内存(Production memory):规则(Rules)存储在`Drools`引擎中的位置. * 工作内存(Working memory):事实(Facts)存储在`Drools`引擎中的位置. * 议程(Agenda): 满足条件的规则准备执行的位置. > 当业务用户或自动化系统往`Drools`引擎中添加事实(Facts)时, 这些事实被存储在`Drools`引擎的工作内存(Working memory)中, `Drools`引擎将这些事实与存储在生产内存(Production memory)中的规则(Rules)条件进行匹配,以确定符合条件的规则执行(这种将事实与规则匹配的过程通常称为模式匹配(pattern matching)). 当满足规则条件时,`Drools`引擎激活并在议程中(Agenda)注册规则,然后`Drools`引擎在议程中排序优先或冲突的规则以准备执行。 下图说明了`Drools`引擎的这些基本组件 ![](/usr/uploads/2021/06/1742607267.png) * `Drools`引擎中的执行逻辑 * 议程评估(Agenda evaluation): 在这个阶段, `Drools`引擎选择所有可以执行的规则. 如果不存在可执行规则, 则执行周期结束. `如果找到可执行规则,Drools`引擎会在议程(Agenda)中注册激活, 然后进入工作记忆操作阶段以执行规则满足后的动作. * 工作内存动作(Working memory actions): 在此阶段,`Drools`引擎为之前在议程(Agenda)中注册的所有已激活规则执行`Action`操作。在所有操作完成或主`Java`应用程序进程再次调用`fireAllRules()`后,`Drools`引擎返回议程评估(Agenda evaluation)阶段重新评估规则. ![](/usr/uploads/2021/06/2186420412.png) ## **为什么是`Drools`** * 专业 * 足够灵活 * 与Java的深度互操作性 * 能够与[jBMP](https://www.jbpm.org/)集成支持业务流程处理能力 * 文档足够全面 * 业内使用者众多 * 开源 ## **入门** ### **安装及开发环境配置** 安装请走传送门[Installing Drools Tooling](https://nicolas-heron.gitbook.io/droolsonboarding/drools/installing_drools_tooling). * Visual Studio Code 开发环境安装 * None ### **`DRL(Drools Rule Language)`** `DRL`是一种`DLS(Domain Specific Language)`语言, 它专门为某个专业的特殊领域编写, 旨在提高领域内的编程效率, `DRL`即是为了方便我们编写业务规则而产生的, 它的基本语法非常简单, 既通过三个关键字即可编写规则: ```drl # import package import com.example.demo.User rule "your first rule" when # conditions User() then # action System.out.println("user exist"); end ``` 如上, 你可以像在`java`里一样导入文件, `when`关键字定义条件, `then`关键字定义满足条件后执行的动作, 在`then`里你可以使用纯`java`代码. 更多的语法你可以在`Drools`[官方文档](https://docs.jboss.org/drools/release/7.55.0.Final/drools-docs/html_single/index.html#drl-rules-con_drl-rules)中找到. ### **BPMN2** * None ## **Drools业务中心(Business Central)** * None ## **结尾** 业务规则是复杂的且变化快速的, 传统在代码里面硬写业务逻辑, 会导致大量的`if-else`判断, 并且业务的不断变更也会使得代码经常改动变得难以维护. Drools的出现很好的解决了这一难题, 它能够将业务规则的变化部分迁移到`规则文件`中, 而代码则是编写利于维护的不常变更的部分, 这不仅是业务规则这个领域的问题, 更多的还是一种思想上的东西, 将变化的业务从代码中剥离出来, 从而构造一个稳定的系统. # Reference * [Drools Introduction](https://nicolas-heron.gitbook.io/droolsonboarding/) * [Drools Documentation](https://docs.jboss.org/drools/release/7.55.0.Final/drools-docs/html_single/index.html#_welcome) * [RulesEngine](https://martinfowler.com/bliki/RulesEngine.html) * [Domain Specific Languages](https://martinfowler.com/books/dsl.html) * [Production Rule System](https://martinfowler.com/dslCatalog/productionRule.html) * [What is Rule-Engine](https://medium.com/@er.rameshkatiyar/what-is-rule-engine-86ea759ad97d) 最后修改:2021 年 06 月 28 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏
3 条评论
确实有点东西
有点东西 φ( ̄∇ ̄o)
但不多