Drools业务规则管理系统25_Drools入门案例3

一、业务场景说明

 业务场景:消费者在图书商城购买图书,下单后需要在支付页面显示订单优惠后的价格。具体优惠规则如下:

  

二、开发实现

 1、创建maven工程drools_quickstart并导入drools相关核心依赖的maven坐标

        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>7.6.0.Final</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

 2、根据drools要求创建resources/META-INF/kmodule.xml配置文件
  注意:上面配置文件的名称和位置都是固定写法,不能更改

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

  

 3、创建实体类Order

package com.itheima.drools.entity;

import lombok.Data;

/**
 * @author wql
 * @date 2021/12/12 19:57
 */
@Data
public class Order {
    /**
     * 订单原始价格,即优惠前价格
     */
    private Double originalPrice;

    /**
     * 订单真实价格,即优惠后价格
     */
    private Double realPrice;
}

 4、创建规则文件resources/rules/bookDiscount.drl

//图书优惠规则
package
book.discount //并不一定是一个真实的目录,是一个逻辑的概念 import com.itheima.drools.entity.Order //规则一:所购图书总价在100元以下的没有优惠 rule "book_discount_1" when $order:Order(originalPrice < 100) //模式匹配,到规则引擎(工作内存)中查找Order对象,并起别名order then $order.setRealPrice($order.getOriginalPrice()); System.out.println("成功匹配到规则一:所购图书总价在100元以下的没有优惠"); end //规则二:所购图书总价在100到200元的优惠20元 rule "book_discount_2" when $order:Order(originalPrice < 200 && originalPrice >= 100) then $order.setRealPrice($order.getOriginalPrice() - 20); System.out.println("成功匹配到规则二:所购图书总价在100到200元的优惠20元"); end //规则三:所购图书总价在200到300元的优惠50元 rule "book_discount_3" when $order:Order(originalPrice <= 300 && originalPrice >= 200) then $order.setRealPrice($order.getOriginalPrice() - 50); System.out.println("成功匹配到规则三:所购图书总价在200到300元的优惠50元"); end //规则四:所购图书总价在300元以上的优惠100元 rule "book_discount_4" when $order:Order(originalPrice >= 300) then $order.setRealPrice($order.getOriginalPrice() - 100); System.out.println("成功匹配到规则四:所购图书总价在300元以上的优惠100元"); end

 5、编写单元测试

  @Test
    public void Test01() {
        KieServices kieServices = KieServices.Factory.get();
     //获得Kie容器对象 KieContainer kieClasspathContainer
= kieServices.getKieClasspathContainer(); //会话对象,用于和规则引擎交互 KieSession kieSession = kieClasspathContainer.newKieSession(); //Fact对象,事实对象。构造订单对象,设置原始价格,由规则引擎根据优惠规则计算优惠后的价格 Order order = new Order(); order.setOriginalPrice(210D); //将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配 //将Order对象插入到规则引擎(工作内存)中
     kieSession.insert(order);
//激活规则引擎,由Drools框架自动进行规则匹配,如果规则匹配成功则执行规则 kieSession.fireAllRules(); //关闭会话 kieSession.dispose(); System.out.println("优惠前原始价格:" + order.getOriginalPrice() +",优惠后价格:" + order.getRealPrice()); }

 6、测试结果:

  

 通过上面的入门案例我们可以发现,使用drools规则引擎主要工作就是编写规则文件,在规则文件中定义跟业务相关的业务规则,例如本案例定义的就是图书优惠规则。规则定义好后就需要调用drools提供的API将数据提供给规则引擎进行规则模式匹配,规则引擎会执行匹配成功的规则并将计算的结果返回给我们。

 可能大家会有疑问,就是我们虽然没有在代码中编写规则的判断逻辑,但是我们还是在规则文件中编写了业务规则,这跟在代码中编写规则有什么本质的区别呢?

 我们前面其实已经提到,使用规则引擎时业务规则可以做到动态管理。业务人员可以像管理数据一样对业务规则进行管理,比如查询、添加、更新、统计、提交业务规则等。这样就可以做到在不重启服务的情况下调整业务规则。

三、小结

 1、规则引擎构成

  drools规则引擎由以下三部分构成:

    • Working Memory(工作内存)
    • Rule Base(规则库)
    • Inference Engine(推理引擎)

   其中Inference Engine(推理引擎)又包括:

    • Pattern Matcher(匹配器) 具体匹配哪一个规则,由这个完成
    • Agenda(议程)
    • Execution Engine(执行引擎)

    

 2、相关概念说明

  • Working Memory:工作内存

   drools规则引擎会从Working Memory中获取数据并和规则文件中定义的规则进行模式匹配,所以我们开发的应用程序只需要将我们的数据插入到Working Memory中即可
例如本案例中我们调用kieSession将order对象插入到了工作内存中。

  • Fact:事实

   是指在drools 规则应用当中,将一个普通的JavaBean插入到Working Memory后的对象就是Fact对象,例如本案例中的Order对象就属于Fact对象。Fact对象是我们的应用和规则引擎进行数据交互的桥梁或通道。

  • Rule Base:规则库

   我们在规则文件中定义的规则都会被加载到规则库中。

  • Pattern Matcher:匹配器

   将Rule Base中的所有规则与Working Memory中的Fact对象进行模式匹配,匹配成功的规则将被激活并放入Agenda中。

  • Agenda:议程

   用于存放通过匹配器进行模式匹配后被激活的规则。

  • Execution Engine:执行引擎

   执行Agenda中被激活的规则。

四、规则引擎执行过程

  

  (1) 将初始数据(fact)输入至工作内存(working Memory)
  (2) 使用Pattern Matcher将规则库中的规则(rule)和数据(fact)比较
  (3) 如果执行规则存在冲突(conflict),即同时激活了多个规则,将冲突的规则放入冲突集合
  (4) 解决冲突,将激活的规则按顺序放入Agenda
  (5) 执行Agenda中的规则,重复2-5,直到执行完毕Agenda中的所有规则

五、KIE介绍

 我们在操作Drools时经常使用的API以及它们之间的关系如下图:

  

 通过上面的核心API可以发现,大部分类名都是以Kie开头。Kie全称为Knowledge Is Everything,即"知识就是一切"的缩写,是Jboss一系列项目的总称。如下图所示,Kie的主要模块有OptaPlanner、Drools、UberFire、jBPM。

  

 通过上图可以看到,Drools是整个KIE项目中的一个组件,Drools中还包括一个Drools-WB的模块,它是一个可视化的规则编辑器。

 

posted on 2024-03-28 15:06  花溪月影  阅读(17)  评论(0编辑  收藏  举报