1 前言

  1. 曾经接触过一个电信移动通讯项目,每个案件大量的业务逻辑变更,但其实里面的业务改动,其实就是一些业务逻辑变动。

而程序员编写的代码也没有任何技术含量,跟着式样书逐字逐句的翻译就行。大量的if/else判断遍布整个项目,维护难度极大。

而这个drools规则引擎,可以方便的将业务的整体逻辑移出,更加方便程序的可读性。

2 准备

2.1 第一步,随便创建maven项目

  1. 创建一个空项目。

2.2 第二步,pom的引入

  1. <dependency>
  2. <groupId>org.drools</groupId>
  3. <artifactId>drools-compiler</artifactId>
  4. <version>7.10.0.Final</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>junit</groupId>
  8. <artifactId>junit</artifactId>
  9. <version>4.12</version>
  10. </dependency>

2.3 第三步,配置文件

src\main\resources\META-INF*_ 下面创建_kmodule.xml文件

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

2.4 第四步,创建规则文件夹

src\main\resources\rules 下面创建 规则文件,规则文件可以以drl为结尾,xml为结尾。

2.4.1 案例一

2.4.1.1 首先创建bean

  1. package com.hikktn.drools.entity;
  2. /**
  3. * @ClassName Order
  4. * @Description 订单
  5. * @Author lisonglin
  6. * @Date 2021/3/27 21:46
  7. * @Version 1.0
  8. */
  9. public class Order {
  10. private Double originalPrice;//订单原始价格,即优惠前价格
  11. private Double realPrice;//订单真实价格,即优惠后价格
  12. public String toString() {
  13. return "Order{" + "originalPrice=" + originalPrice + ", realPrice=" + realPrice + '}';
  14. }
  15. public Double getOriginalPrice() {
  16. return originalPrice;
  17. }
  18. public void setOriginalPrice(Double originalPrice) {
  19. this.originalPrice = originalPrice;
  20. }
  21. public Double getRealPrice() {
  22. return realPrice;
  23. }
  24. public void setRealPrice(Double realPrice) {
  25. this.realPrice = realPrice;
  26. }
  27. }

2.4.1.2 创建bookDiscount.drl文件

建立相应规则

  1. // 图书优惠策略
  2. package book.discount;
  3. // 引入项目
  4. import com.hikktn.drools.entity.Order;
  5. dialect "mvel"
  6. // 规则一:所购图书总价在100元以下的没有优惠
  7. rule "book_discount_1"
  8. when
  9. $order:Order( originalPrice < 100 ) // 模式匹配
  10. then
  11. $order.setRealPrice($order.getOriginalPrice());
  12. System.out.println("没有优惠");
  13. end
  1. @Test
  2. public void test2(){
  3. // 获取规则引擎
  4. KieServices kieServices = KieServices.Factory.get();
  5. // 获取连接
  6. KieContainer kieContainer = kieServices.getKieClasspathContainer();
  7. // 创建会话1
  8. KieSession kieSession = kieContainer.newKieSession();
  9. // 构造订单
  10. Order order =new Order();
  11. order.setOriginalPrice(50.0);
  12. // 添加事件
  13. kieSession.insert(order);
  14. kieSession.fireAllRules();
  15. // 关闭会话
  16. kieSession.dispose();
  17. }

2.4.1.3 结果

没有优惠

2.4.2 案例二

2.4.2.1 衍生规则

两个订单不同的规则,不会触发到其他的规则

  1. AgendaFilter 增加过滤规则<br /> RuleNameEqualsAgendaFilter 执行名称全匹配的规则<br /> RuleNameEndsWithAgendaFilter 执行名称以xxx结尾的规则<br /> RuleNameMatchesAgendaFilter 可以写自己的正则<br /> RuleNameStartsWithAgendaFilter 执行名称以xxx开头的规则<br /> RuleNameSerializationAgendaFilter 规则名称序列化代理筛选器
  1. // 规则四:所购图书总价在300元以上的优惠100元
  2. rule "book_discount_4"
  3. when
  4. $order:Order(originalPrice >= 300)
  5. then
  6. $order.setRealPrice($order.getOriginalPrice() - 100);
  7. System.out.println("优惠100元");
  8. end
  9. // 规则二:所购图书总价在100到200元的优惠20元
  10. rule "book_discountA"
  11. when
  12. $order:Order( originalPrice < 200 && originalPrice >= 100 ) // 模式匹配
  13. then
  14. $order.setRealPrice($order.getOriginalPrice() - 20);
  15. System.out.println("订单优惠了20元");
  16. end
  1. @Test
  2. public void test1(){
  3. // 获取规则引擎
  4. KieServices kieServices = KieServices.Factory.get();
  5. // 获取连接
  6. KieContainer kieContainer = kieServices.getKieClasspathContainer();
  7. // 创建会话1
  8. KieSession kieSession = kieContainer.newKieSession();
  9. // 创建会话2
  10. KieSession kieSession2 = kieContainer.newKieSession();
  11. // 构造订单
  12. Order order =new Order();
  13. order.setOriginalPrice(500.0);
  14. Order order2 =new Order();
  15. order2.setOriginalPrice(100D);
  16. // 添加订单,针对订单进行规则交互计算
  17. kieSession.insert(order);
  18. kieSession2.insert(order2);
  19. // 激活规则引擎
  20. kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("book_discount_"));
  21. // AgendaFilter 增加过滤规则
  22. // RuleNameEqualsAgendaFilter 执行名称全匹配的规则
  23. // RuleNameEndsWithAgendaFilter 执行名称以xxx结尾的规则
  24. // RuleNameMatchesAgendaFilter 可以写自己的正则
  25. // RuleNameStartsWithAgendaFilter 执行名称以xxx开头的规则
  26. // RuleNameSerializationAgendaFilter 规则名称序列化代理筛选器
  27. kieSession2.fireAllRules(new RuleNameEqualsAgendaFilter("book_discountA"));
  28. // 关闭会话
  29. kieSession.dispose();
  30. kieSession2.dispose();
  31. System.out.println("订单1的原价格:"+order.getOriginalPrice()+ ",优惠价格:"+order.getRealPrice());
  32. System.out.println("订单2的原价格:"+order.getOriginalPrice()+ ",优惠价格:"+order2.getRealPrice());
  33. }

2.4.2.2 结果

优惠100元
订单优惠了20元
订单1的原价格:500.0,优惠价格:400.0
订单2的原价格:500.0,优惠价格:80.0