Drools规则引擎

一、“规则引擎”介绍

        规则引擎是由推理引擎变化而来,并不特指某个技术框架,它可以是一个系统,也可以是一个软件的适配类组件,甚至是软件本身。规则引擎主要作用是管理和执行规则,将复杂化的执行过程通过简易的规则组合拆分,通过特定的规则组合,降低业务逻辑的复杂程度和后期维护成本,同时提高其可扩展性。

二、Drools规则引擎介绍

1.背景

        Drools 是用 Java 语言编写的开源规则引擎,是KIE(知识就是一切)项目的一部分,基于Charles Forgy的RETE算法的规则引擎实现。其使用 ReteOO算法执行规则。支持使用自然语言表达业务逻辑,也可以使用 Java/Groovy/Python + XML 语法编写规则。 早期的版本一般由开发人员通过开发工具插件来定义规则,目前已有Drools Workbench通过web服务提供给业务人员维护规则。 Drools 还具有以下优点:

非常活跃的社区
生态不断的完善中
JSR 94 兼容(JSR 94 是 Java Rule Engine API)
免费

Drools规则引擎基于以下抽象组件实现:

  • 规则(Rules):业务规则或DMN决策。所有规则必须至少包含触发该规则的条件以及对应的操作。
  • 事实(Facts):输入到规则引擎的数据,用于规则的条件的匹配。
  • 生产内存(Production memory):规则引擎中规则存储的地方
  • 工作内存(Working memory):规则引擎中Fact对象存储的地方。
  • 议程(Agenda):用于存储被激活的规则的分类和排序的地方。

当用户或系统在Drools中添加或更新规则相关的信息时,该信息会以一个或多个事实的形式插入Drools规则引擎的工作内存中。Drools规则引擎匹配事实和存储在生产内存中规则,筛选符合执行条件的规则。对于满足条件的规则,规则引擎会在议程中激活和执行。

        Drools 被分为两个主要的部分:编译和运行时。编译是将规则描述文件按 ANTLR 3 语法进行解析,对语法进行正确性的检查,然后产生一种中间结构“descr”,descr 用 AST 来描述规则。目前,Drools 支持四种规则描述文件,分别是:drl 文件、 xls 文件、brl 文件和 dsl 文件,其中,常用的描述文件是 drl 文件和 xls 文件,而 xls 文件更易于维护,更直观,更为被业务人员所理解。运行时是将 AST传到 PackageBuilder,由 PackagBuilder来产生 RuleBase,它包含了一个或多个 Package 对象。

2.应用

        因为Drools主要针对于JAVA,此处主要描述JAVA开发对Drools的应用。

  1. maven依赖

            <dependency>
                <groupId>org.drools</groupId>
                <artifactId>drools-core</artifactId>
                <version>7.8.0.Final</version>
            </dependency>
            <dependency>
                <groupId>org.drools</groupId>
                <artifactId>drools-compiler</artifactId>
                <version>7.8.0.Final</version>
            </dependency>
            <dependency>
                <groupId>org.drools</groupId>
                <artifactId>drools-mvel</artifactId>
                <version>7.69.0.Final</version>
            </dependency>
  2. 规则文件
    Drools的规则文件一般有xls、drl、dsl、brl几种,此处介绍drl(Drools Rule Language)文件类型。

    一套完整的规则文件内容构成如下:
     

    package包名,只限于逻辑上的管理,同一个包名下的查询或者函数可以直接调用
    import用于导入类或者静态方法
    global全局变量
    function自定义函数
    query查询
    rule end规则体
    ​​​​
  3. 规则体是规则文件内容中的重要组成部分,是进行业务规则判断、处理业务结果的部分。

    规则体语法结构如下:

    rule "ruleName"
        attributes
        when
            LHS
        then
            RHS
    end
    

    rule:关键字,表示规则开始,参数为规则的唯一名称。

    attributes:规则属性,是rule与when之间的参数,为可选项。

    when:关键字,后面跟规则的条件部分。

    LHS(Left Hand Side):是规则的条件部分的通用名称。它由零个或多个条件元素组成。如果LHS为空,则它将被视为始终为true的条件元素。

    then:关键字,后面跟规则的结果部分。

    RHS(Right Hand Side):是规则的后果或行动部分的通用名称。

    end:关键字,表示一个规则结束。

  4. 使用方式
    举个例子,充会员送money。
    ①配置Drools的kmodule.xml文件。主要是告诉Drools规则文件在哪,然后都有什么session等等属性,文件放在resource/META-INF目录下。样例如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <kmodule xmlns="http://www.drools.org/xsd/kmodule">
        <!--
        name:指定kbase的名称,可以任意,但是需要唯一
        packages:指定规则文件的目录,需要根据实际情况境写,否则无法加载到规则文件
        default:指定当前kbase是否为默认
        -->
        <kbase name="userKbase" packages="drools" default="true">
            <!--
            name:指定ksession名称,可以任意,但是需要唯一
            default:撒定当前session是否为默认
            -->
            <ksession name="ksession-rule" default="true"/>
        </kbase>
    </kmodule>

    ②规则文件如下,随便放吧,只要能跟上面的xml文件的package能对上就行。

    import org.example.entity.Cus
    import java.math.BigDecimal
    rule "rule1"
        when $cus : Cus(money<50)
        then $cus.setMoney($cus.getMoney());
    end
    rule "rule2"
        when $cus : Cus(money<100 && money>=50)
        then $cus.setMoney($cus.getMoney().add(BigDecimal.valueOf(30)));
    end
    rule "rule3"
        when $cus : Cus(money>=100)
        then $cus.setMoney($cus.getMoney().add(BigDecimal.valueOf(100)));
    end

    ③简单的调用代码

            KieServices kieServices = KieServices.Factory.get();
            KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
            // session 如果相同,想要改变数据需要使用kieContainer的update方法,并在之后使用dispose
            KieSession kieSession = kieClasspathContainer.newKieSession();
            Cus cus = new Cus();
            cus.setMoney(BigDecimal.valueOf(100));
            kieSession.insert(cus);
            kieSession.fireAllRules();
            kieSession.dispose();
            System.out.println(cus.getMoney());

    ④单元测试调用结果如下




     

  • 46
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值