使用 Drools 构建业务规则引擎 - 中小企业的力量

已发表: 2022-03-11

从事软件开发工作最令人惊奇的事情之一就是能够在许多不同的行业工作——尤其是如果你是一名顾问。 您在一个行业工作时学到的大多数软件开发技能都可以直接转移到任何数量的其他行业、公司、项目和利基市场。

我说的是数据库设计、设计模式、GUI 布局、事件管理等主题。当然,还有针对特定行业、公司或项目的主题。

中小企业遇上 IT,知识转移开始

这就是主题专家 (SME) 的用武之地。SME 通常会非常参与项目的设计阶段。

SME在行业内工作了很长时间,懂行话,懂编码背后的业务逻辑。 中小企业可能对软件开发有一定的了解,但这并不是项目成功的必要条件。

对于很多项目来说,除非软件开发者对业务逻辑有深入的了解,否则完成一个成功的软件应用程序会比较困难。 需要花费在知识转移上的时间量将根据项目的复杂性而有很大差异。

假设采用敏捷方法并且在整个项目开发阶段有一个或多个 SME 可用,则知识转移将在项目的所有阶段继续进行。

如果完全的知识转移不可行怎么办?

取决于行业和项目,中小企业可能无法提供完整的知识转移。

例如,假设 SME 是一位拥有 25 年经验的医生,而您有 6 个月的时间来完成一个项目。 或者,将 SME 想象成拥有 40 年经验的生物学家——这样的知识水平根本无法在软件开发项目的现实时间框架内转移。

但是如果知识领域是动态的呢?

通常,软件会根据时间或功能按设定的时间表发布。 但是,某些行业的业务规则变化得更频繁。

在许多情况下,为了跟上行业变化而频繁发布软件可能是不可行的。 在这种情况下,能够在业务规则引擎中外部化业务规则可能是有意义的。 软件项目能够承受变化的能力将大大有助于确保其最终的长期成功。

规则引擎何时何地有意义?

对于许多软件项目,完全的知识转移是可行的,并且业务逻辑可以用计算机语言(如 C# 或 Java)进行编码。

但是,有一部分项目对特定主题的理解量如此之大,或者业务规则受到如此多的更改,以至于非程序员直接访问业务逻辑更有意义。 这是本教程的主题; 考虑到这一点,让我们深入讨论规则引擎。

什么是业务规则引擎?

规则引擎是用于执行业务规则的工具。 业务规则由事实和条件语句组成。 任何出现在传统业务逻辑中的“if-then”语句都符合业务规则。

业务规则引擎

例如:如果员工连续生病超过 5 天且没有医生证明,需要将其记录下来。 如果超过 6 个月没有联系业务伙伴并且他们在此期间没有进行任何购买,那么可能是时候向他们发送一封诚挚的电子邮件了。 如果患者体温高、视力有问题,并且有青光眼家族史,那么可能是时候要求进行额外的 MRI 或其他检查了。

中小企业如何编写业务规则?

IT 不会期望 SME 学习 Java、C# 或其他编程语言,而是会为他或她创建一种迷你语言来表达他们的业务规则。 这些规则的构建块将包含可以查询的事实。 按行业/实践领域划分的一些事实示例如下:

  • 人力资源:薪水、职位、经理、在公司工作的年限
  • 医疗:体温、血压、当前用药
  • 财务:当前股价、52 周最高/最低价、市盈率、下一次财报发布日期

从本质上讲,必须以简化的方式为 SME 提供做出业务决策所需的信息。

这些规则是什么样的?

在本规则引擎教程的其余部分,我将使用 Drools,这是一个基于 Java 的开源规则引擎,可以在 www.drools.org 找到,它是一个 JBoss 项目。 在 Drools 中,规则被编写为 Java 代码并具有以下结构:

导入语句在这里:

 rule “Name of rule” when “The if” part of the business logic goes here. then The “then” part of the business logic goes here. end

流口水和工作记忆

Drools 采用了一个称为工作记忆的概念。

应用程序代码将负责将适当的事实加载到工作内存中,以便 SME 可以编写查询这些事实的规则。 只有与应用程序业务逻辑相关的事实才应加载到工作内存中,以保持规则引擎以最高速度运行。

例如,如果应用程序正在确定是否批准客户的贷款,则相关事实将包括工资、信用评分和未偿贷款。 不相关的事实将包括星期几或性别。

规则评估

在 Drools 工作记忆加载了规则和事实后,规则会根据规则的“then”部分进行评估。 如果“then”部分的计算结果为 true,则将执行规则的“when”部分。

通常,所有规则都会被一次评估,尽管可以将规则组合在一起并在每个组的基础上进行评估。 规则的“then”部分可以改变工作记忆的内容。 发生这种情况时,Drools 将重新评估所有规则以查看是否有任何规则现在评估为真。 如果是这样,它们的“何时”部分将被执行。

规则评估的这种递归性质可能是福也可能是祸——因此在创建规则时需要牢记这种架构。

Drools 规则的“如果”方面

在 Drools 中,事实由对象表示。 可以查询对象类型的存在或不存在。 此外,还可以查询对象的属性。

这里有一些例子:

确定员工的收入是否超过 100,000。

 Employee(salary > 100000)

确定患者的胆固醇水平是否高于 200 并正在服用立普妥。

 Patient(cholesterol > 200, medications.contains(“lipitor”))

确定股票价格是否在其年度最高价的 1% 以内。

 Stock(price >= (yearHigh * .99))

组合查询

在编写复杂的业务逻辑时,业务规则可以通过使用布尔运算符 AND、OR 和 NOT 以及使用括号进行嵌套来组合查询。

例如:

确定是否有一名经理的收入低于 75,000 美元或一名董事的收入低于 100,000 美元。

 Employee(position.Equals(“Manager”),salary<75000) OR Employee(position.Equals(“Directory”),salary<100000)

使用多种对象类型

到目前为止,所有示例都基于单一对象类型,例如 Employee 或 Patient。 然而,Drools 允许查询基于多种对象类型。

例如:

确定客户的薪水是否高于 50,000 美元并且尚未申请破产。

 Customer(salary>50000) AND not exists Bankruptcy()

规则的“当时”一面

规则的“then”部分决定了当规则的“when”部分至少有一个结果时会发生什么。

在 Drools 中,任何可以用 Java 编写的东西都可以写在规则的“then”部分。 但是,为了使规则更可重用,最好不要在规则中放置任何 I/O、流控制代码或一般执行代码。

作为替代方案,规则的“then”部分可用于修改工作记忆。 一种常见的做法是在规则被评估为真时将事实插入到工作记忆中。

例如:

 rule “LoanApproved” when Customer(credit>700) && not exist LoanOutstanding() then insert(new LoanApproval()) end

我们如何知道规则何时被评估为真?

触发所有规则后,应用程序需要知道哪些规则被评估为真。 如果规则在评估为真时将对象插入到工作内存中,则可以编写代码来查询这些对象的工作内存。

在上面的例子中,在所有规则都被触发之后,可以进行查询以查看 LoanApproval() 对象是否在工作内存中。

 query "GetLoanApproval " $result: LoanApproval() end

业务规则引擎如何与应用程序交互?

典型应用程序包含业务逻辑、GUI、I/O 和控制代码流。

例如,应用程序可能会像这样处理用户请求:

 GUI ? Flow Control ? I/O ? Business Logic ? I/O ? Flow Control ? GUI

嵌入规则引擎会为此过程添加几个步骤:

 GUI ? Flow Control ? I/O ? Create Rules Engine Session ? Add Facts to Working Memory ? Fire Rules ? Determine which rules have evaluated true ? I/O ? Flow Control ? GUI

中小企业如何使用规则?

创建、编辑和删除规则

为了让 SME 使用规则,他们需要一个用户友好的 GUI。 一些业务规则引擎附带这样的接口。

例如,Drools 附带了两个我认为用户友好的 GUI。 第一个类似于电子表格,允许中小企业创建规则而无需编写任何实际代码。 第二个 GUI 允许创建更复杂的业务逻辑。

虽然这两个 GUI 都有助于输入简单的条件,但随着业务逻辑变得更加复杂,它们将不起作用。 在这种情况下,您必须创建自己的自定义 GUI。

SME 自定义 GUI 的元素

为了使 SME 有效工作,请考虑创建具有以下功能的自定义 GUI:

  • 语法检查器——“检查语法”按钮可以调用 Drools 代码来检查可能的错误及其行号。
  • 拖放 - 与其要求 SME 记住他们可用的对象和属性,不如考虑为他们提供一个选择列表,他们可以从中拖放。
  • Web 界面 – 中小企业可以使用瘦客户端界面,无需担心分配问题。 这将派上用场,因为 GUI 需要附加功能和一般维护。
  • Rule Tester – 能够在不与整个应用程序交互的情况下测试单个规则将大大提高 SME 的生产力。 允许 SME GUI 确定事实,然后触发个别规则。

规则应该存储在哪里?

在 Drools 中,通常有两种存储规则的方法。 Drools 开箱即用,基于文件的规则通常具有 .drl 扩展名。

当规则的数量很少时,这很有效。 随着规则数量的增加,您将需要使用数据库。 从数据库存储和检索规则需要更多的工作,但应该为您提供更易于管理的架构。

本规则引擎教程仅涉及 Drools 规则语言的一小部分。 有关完整说明,请参阅官方参考文档。

不应轻易做出使用规则引擎的决定。 虽然规则引擎将使您的应用程序更容易被 SME 扩展,但它的开发、测试和部署也会变得更加复杂。 有关此主题的其他注意事项,您可能需要查看以下指南。

现在我们可以继续向您展示一些更有趣的东西——一个简单的 Drools 实际示例,在大多数 Toptal 博客读者应该熟悉的用例中。

在真实场景中使用 Drools

Toptal 是高级软件开发人才的领先供应商,目前使用申请人跟踪软件在招聘过程的各个阶段引导求职者。 这是此过程的简化可视化流程图:

流口水

目前,决定应聘者是否继续招聘流程的业务逻辑已被硬编码到软件中。 每次人力资源部需要更改业务逻辑时,都必须让 IT 参与其中。 他们希望能够直接改变他们的软件运行方式。

申请人跟踪软件将被修改为在招聘过程中的每个决策点运行 HR 提供的规则。 HR 将有一个“候选人”对象,该对象将代表一个求职者,该求职者的状态刚刚因初次进入、完成在线考试或许多不同的因素而被修改。 Candidate 对象将具有表示经验、考试成绩、面试成绩等的字段。

以下示例提供了一组简化的规则供您考虑。 它还没有被部署,它只是一个简单的例子,由四个相互关联的规则组成:

  • 已提交 -> 测试
  • 测试 -> 面试
  • 面试 -> 项目
  • 项目 -> 招聘

已提交 -> 测试

根据当前客户的需求,HR 想编写一个规则来确定是否应安排候选人进行在线测试。

 Rule “Schedule For Testing” when $candidate: Candidate(status=='Submitted',yrsExperience >= 10, skill(name=='Java', yrsExperience>=5) or Skill(name=='C#', yrsExperience>=5)) then $candidate.setStatus('Testing'); end

测试 -> 面试

候选人参加在线考试后,需要评估他们的分数。 HR 也想控制这条规则。 在线考试测试考生理解软件开发理论、解决问题和语法的能力。 HR 想决定什么样的分数组合可以让候选人被考虑参加技术面试。

 Rule “Schedule For Interview” when $candidate: Candidate(status=='Testing', testScore(theory>.8 && syntax>.6 && problemSolving>.8); then $candidate.setStatus('Interview'); end

面试 -> 项目

技术面试将测试候选人谈论他们的经验、回答问题解决问题的能力,并将测试他们的一般沟通能力。 HR 将编写确定技术面试及格分数的规则。

 Rule “Schedule For Project” when $candidate: Candidate(status=='Interview', interviewScore(speakExperience>.9 && problemSolving>.8 && communication>.9 ); then $candidate.setStatus('Project'); end

项目 -> 招聘

如果候选人通过了技术面试,他们将获得一个离线编程项目。 他们将提交项目,并将根据完整性、架构和 GUI 进行评判。

 Rule “Schedule For Hiring” when $candidate: Candidate(status=='Project', projectScore(completeness>.8 && architecture>.9 && gui>.7 ); then $candidate.setStatus('Hiring'); end

如您所见,即使是这个基本示例也为 HR 提供了许多可能性,并且可以简化操作。 HR 无需 IT 参与即可更改规则这一事实将不可避免地节省时间并加快筛选过程。

由于可以随时更改规则,因此人力资源部门也将拥有更大的灵活性。 例如,HR 可以通过设置不同的参数来扩展或限制选择过程。

如果有太多候选人勾选了所有正确的框,则可以在几分钟内提高标准,从而减少候选人的数量。 或者,如果该过程产生的候选人很少或没有满足所有要求,HR 可以选择降低或放弃一些标准,将重点转移到更相关的技能上,直到有足够数量的候选人满足要求。