# 什么是规则引擎

规则引擎是一种软件系统,它使用预定义的规则集来做出决策或执行操作。它通常用于处理复杂、多变的业务逻辑,使得这些逻辑的变更和维护不必通过硬编码的方式实现,从而提高系统的灵活性和可扩展性。本文重点讲述工作流引擎中如何使用规则引擎。如需在线体验,请访问www.jeecgflow.com (opens new window)

添加图片注释,不超过 140 字(可选)

规则引擎的特点

  1. 规则管理:规则引擎允许非技术人员通过友好的界面定义、修改、测试和部署业务规则。
  2. 条件匹配:引擎会根据输入数据与规则条件进行匹配,以决定哪些规则应当被触发。
  3. 自动执行:一旦规则被触发,相应的动作会被自动执行,无需人工干预。
  4. 松耦合设计:规则与业务逻辑分离,使得规则的变更不会影响到其他系统组件。

企业应用

  • 信贷评分:根据申请人的信息,自动决定是否批准贷款。
  • 保险理赔:根据理赔规则自动处理保险索赔。
  • 电子商务:个性化推荐系统,基于用户行为和偏好调整推荐内容。
  • 监控系统:根据系统状态自动触发警告或维护操作。

简单理解就是系统先设置规则,然后接收数据,输出结果。先声明后执行的意思。

在工作流引擎方面,目前camunda和flowable两款产品提供了比较好的规则引擎的实现方案。本文主要以camunda实现DMN规则引擎进行案例解析。 帮助您快速理解规则引擎如何运作!

# 需求分析

通过幼儿园学生年龄age和身高height分配不同的班级,决策表可随时修改。校长审核时向流程中传递决策表所需要的流程变量age、height。流程径流决策表后自动提交到相关班级老师审批。
决策规则说明
大于3岁并且身高高于70cm,可上幼儿园小班
大于等于5岁并且身高高于95cm,可上幼儿园中班
大于7岁并且身高高于120cm,可上幼儿园大班

# 流程建模

添加图片注释,不超过 140 字(可选)

整个模型的意思就是通过判断班级这个规则引擎,将输入的参数进行分类。

添加图片注释,不超过 140 字(可选)

DMN规则引擎节点如何进行配置的说明

# XML内容

    <?xml version="1.0" encoding="UTF-8"?>
    <bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
      <bpmn:process id="Process_choice_class" name="班级决策" isExecutable="true">
        <bpmn:startEvent id="StartEvent_1">
          <bpmn:outgoing>Flow_0fss2gh</bpmn:outgoing>
        </bpmn:startEvent>
        <bpmn:sequenceFlow id="Flow_0fss2gh" sourceRef="StartEvent_1" targetRef="Activity_1nqmntb" />
        <bpmn:userTask id="Activity_1nqmntb" name="校长审核" camunda:assignee="${customer}">
          <bpmn:extensionElements>
            <camunda:formData>
              <camunda:formField id="age" label="年龄" type="long" defaultValue="1" />
              <camunda:formField id="height" label="身高" type="long" defaultValue="0" />
            </camunda:formData>
          </bpmn:extensionElements>
          <bpmn:incoming>Flow_0fss2gh</bpmn:incoming>
          <bpmn:outgoing>Flow_1w7qdzj</bpmn:outgoing>
        </bpmn:userTask>
        <bpmn:sequenceFlow id="Flow_1w7qdzj" sourceRef="Activity_1nqmntb" targetRef="Activity_02itx7s" />
        <bpmn:businessRuleTask id="Activity_02itx7s" name="判断哪个班级" camunda:resultVariable="dmnResult" camunda:decisionRef="class-choice" camunda:mapDecisionResult="singleEntry">
          <bpmn:incoming>Flow_1w7qdzj</bpmn:incoming>
          <bpmn:outgoing>Flow_1hcuyt1</bpmn:outgoing>
        </bpmn:businessRuleTask>
        <bpmn:exclusiveGateway id="Gateway_1c2reel">
          <bpmn:incoming>Flow_1hcuyt1</bpmn:incoming>
          <bpmn:outgoing>Flow_1oukih7</bpmn:outgoing>
          <bpmn:outgoing>Flow_1dghuqc</bpmn:outgoing>
          <bpmn:outgoing>Flow_1ry0dxl</bpmn:outgoing>
        </bpmn:exclusiveGateway>
        <bpmn:sequenceFlow id="Flow_1hcuyt1" sourceRef="Activity_02itx7s" targetRef="Gateway_1c2reel">
          <bpmn:extensionElements>
            <camunda:executionListener delegateExpression="${myClassTask}" event="take" />
          </bpmn:extensionElements>
        </bpmn:sequenceFlow>
        <bpmn:sequenceFlow id="Flow_1oukih7" name="dmnResult==1" sourceRef="Gateway_1c2reel" targetRef="Activity_0jlob3q">
          <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${dmnResult ==1}</bpmn:conditionExpression>
        </bpmn:sequenceFlow>
        <bpmn:serviceTask id="Activity_0jlob3q" name="小班" camunda:delegateExpression="${myClassTask}">
          <bpmn:incoming>Flow_1oukih7</bpmn:incoming>
          <bpmn:outgoing>Flow_121bph1</bpmn:outgoing>
        </bpmn:serviceTask>
        <bpmn:sequenceFlow id="Flow_1dghuqc" name="dmnResult==2" sourceRef="Gateway_1c2reel" targetRef="Activity_08vymo7">
          <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${dmnResult ==2}</bpmn:conditionExpression>
        </bpmn:sequenceFlow>
        <bpmn:serviceTask id="Activity_08vymo7" name="中班" camunda:delegateExpression="${myClassTask}">
          <bpmn:incoming>Flow_1dghuqc</bpmn:incoming>
          <bpmn:outgoing>Flow_0bzrgdf</bpmn:outgoing>
        </bpmn:serviceTask>
        <bpmn:sequenceFlow id="Flow_1ry0dxl" name="dmnResult==3" sourceRef="Gateway_1c2reel" targetRef="Activity_16865do">
          <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${dmnResult ==3}</bpmn:conditionExpression>
        </bpmn:sequenceFlow>
        <bpmn:serviceTask id="Activity_16865do" name="大班" camunda:delegateExpression="${myClassTask}">
          <bpmn:incoming>Flow_1ry0dxl</bpmn:incoming>
          <bpmn:outgoing>Flow_0wftu8w</bpmn:outgoing>
        </bpmn:serviceTask>
        <bpmn:endEvent id="Event_1tksyrl">
          <bpmn:incoming>Flow_121bph1</bpmn:incoming>
        </bpmn:endEvent>
        <bpmn:sequenceFlow id="Flow_121bph1" sourceRef="Activity_0jlob3q" targetRef="Event_1tksyrl" />
        <bpmn:endEvent id="Event_1u2u83d">
          <bpmn:incoming>Flow_0bzrgdf</bpmn:incoming>
        </bpmn:endEvent>
        <bpmn:sequenceFlow id="Flow_0bzrgdf" sourceRef="Activity_08vymo7" targetRef="Event_1u2u83d" />
        <bpmn:endEvent id="Event_0gq7hhn">
          <bpmn:incoming>Flow_0wftu8w</bpmn:incoming>
        </bpmn:endEvent>
        <bpmn:sequenceFlow id="Flow_0wftu8w" sourceRef="Activity_16865do" targetRef="Event_0gq7hhn" />
      </bpmn:process>
    </bpmn:definitions>

# 规则建模

dmn规则引擎定义

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" xmlns:camunda="http://camunda.org/schema/1.0/dmn" xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/" xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/" exporter="Camunda Modeler" exporterVersion="4.11.1" expressionLanguage="https://www.omg.org/spec/DMN/20191111/FEEL/" id="Definitions_appoaprif5r90c" name="DRD" namespace="http://camunda.org/schema/1.0/dmn" typeLanguage="https://www.omg.org/spec/DMN/20191111/FEEL/">
      <decision id="class-choice" name="班级判断">
        <decisionTable aggregation="MAX" hitPolicy="COLLECT" id="DecisionTable_xxe918s1gxq" preferredOrientation="Rule-as-Row">
          <input camunda:inputVariable="A" id="Input_A" label="年龄">
            <inputExpression id="InputExpression_A" typeRef="integer">
              <text>age</text>
            </inputExpression>
          </input>
          <input id="InputClause_1pmyqs4" label="身高">
            <inputExpression id="LiteralExpression_1g9go56" typeRef="number">
              <text>height</text>
            </inputExpression>
          </input>
          <output id="Output_A" label="选择班级" name="dmnResult" typeRef="number"/>
          <rule id="DecisionRule_14e302t">
            <description>大于3岁并且身高高于70cm,可上幼儿园小班</description>
            <inputEntry id="UnaryTests_10f17a9">
              <text>&gt;3</text>
            </inputEntry>
            <inputEntry id="UnaryTests_1juonnl">
              <text>&gt;70</text>
            </inputEntry>
            <outputEntry id="LiteralExpression_0sv3naw">
              <text>1</text>
            </outputEntry>
          </rule>
          <rule id="DecisionRule_1dzzwnr">
            <description>大于等于5岁并且身高高于95cm,可上幼儿园中班</description>
            <inputEntry id="UnaryTests_0m4kz9f">
              <text>&gt;=5</text>
            </inputEntry>
            <inputEntry id="UnaryTests_12y1rvm">
              <text>&gt;=96</text>
            </inputEntry>
            <outputEntry id="LiteralExpression_0wovhui">
              <text>2</text>
            </outputEntry>
          </rule>
          <rule id="DecisionRule_1rgvsjm">
            <description>大于7岁并且身高高于120cm,可上幼儿园大班</description>
            <inputEntry id="UnaryTests_0g02yle">
              <text>&gt;7</text>
            </inputEntry>
            <inputEntry id="UnaryTests_0xhd2bf">
              <text>&gt;120</text>
            </inputEntry>
            <outputEntry id="LiteralExpression_0f71spy">
              <text>3</text>
            </outputEntry>
          </rule>
        </decisionTable>
      </decision>
      <dmndi:DMNDI>
        <dmndi:DMNDiagram>
          <dmndi:DMNShape dmnElementRef="Definitions_hrsxxe918s1gxq" id="DMNShape_8kn0lmvopu7" isCollapsed="false">
            <dc:Bounds height="80" width="180" x="160" y="280"/>
          </dmndi:DMNShape>
        </dmndi:DMNDiagram>
      </dmndi:DMNDI>
    </definitions>

规则定义的源文件

# 演示情况

发起流程-含有规则引擎

登陆JeecgFlow (opens new window)站点找到camunda演示站点,使用账号进行登陆,找到班级决策菜单,提交表单。

运行结果的可视化效果

通过上面的案例,相信大家已经基本理解规则引擎的运作。 也希望大家能意识到规则引擎其实很重要,在一些工具站点或重复性工作场景下,不妨用规则引擎为自己提升效率吧。 www.jeecgflow.com (opens new window)