1 前言
曾经接触过一个电信移动通讯项目,每个案件大量的业务逻辑变更,但其实里面的业务改动,其实就是一些业务逻辑变动。
而程序员编写的代码也没有任何技术含量,跟着式样书逐字逐句的翻译就行。大量的if/else判断遍布整个项目,维护难度极大。
而这个drools规则引擎,可以方便的将业务的整体逻辑移出,更加方便程序的可读性。
2 准备
2.1 第一步,随便创建maven项目
创建一个空项目。
2.2 第二步,pom的引入
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.10.0.Final</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
2.3 第三步,配置文件
在src\main\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>
2.4 第四步,创建规则文件夹
在src\main\resources\rules 下面创建 规则文件,规则文件可以以drl为结尾,xml为结尾。
2.4.1 案例一
2.4.1.1 首先创建bean
package com.hikktn.drools.entity;
/**
* @ClassName Order
* @Description 订单
* @Author lisonglin
* @Date 2021/3/27 21:46
* @Version 1.0
*/
public class Order {
private Double originalPrice;//订单原始价格,即优惠前价格
private Double realPrice;//订单真实价格,即优惠后价格
public String toString() {
return "Order{" + "originalPrice=" + originalPrice + ", realPrice=" + realPrice + '}';
}
public Double getOriginalPrice() {
return originalPrice;
}
public void setOriginalPrice(Double originalPrice) {
this.originalPrice = originalPrice;
}
public Double getRealPrice() {
return realPrice;
}
public void setRealPrice(Double realPrice) {
this.realPrice = realPrice;
}
}
2.4.1.2 创建bookDiscount.drl文件
建立相应规则
// 图书优惠策略
package book.discount;
// 引入项目
import com.hikktn.drools.entity.Order;
dialect "mvel"
// 规则一:所购图书总价在100元以下的没有优惠
rule "book_discount_1"
when
$order:Order( originalPrice < 100 ) // 模式匹配
then
$order.setRealPrice($order.getOriginalPrice());
System.out.println("没有优惠");
end
@Test
public void test2(){
// 获取规则引擎
KieServices kieServices = KieServices.Factory.get();
// 获取连接
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 创建会话1
KieSession kieSession = kieContainer.newKieSession();
// 构造订单
Order order =new Order();
order.setOriginalPrice(50.0);
// 添加事件
kieSession.insert(order);
kieSession.fireAllRules();
// 关闭会话
kieSession.dispose();
}
2.4.1.3 结果
没有优惠
2.4.2 案例二
2.4.2.1 衍生规则
两个订单不同的规则,不会触发到其他的规则
AgendaFilter 增加过滤规则<br /> RuleNameEqualsAgendaFilter 执行名称全匹配的规则<br /> RuleNameEndsWithAgendaFilter 执行名称以xxx结尾的规则<br /> RuleNameMatchesAgendaFilter 可以写自己的正则<br /> RuleNameStartsWithAgendaFilter 执行名称以xxx开头的规则<br /> RuleNameSerializationAgendaFilter 规则名称序列化代理筛选器
// 规则四:所购图书总价在300元以上的优惠100元
rule "book_discount_4"
when
$order:Order(originalPrice >= 300)
then
$order.setRealPrice($order.getOriginalPrice() - 100);
System.out.println("优惠100元");
end
// 规则二:所购图书总价在100到200元的优惠20元
rule "book_discountA"
when
$order:Order( originalPrice < 200 && originalPrice >= 100 ) // 模式匹配
then
$order.setRealPrice($order.getOriginalPrice() - 20);
System.out.println("订单优惠了20元");
end
@Test
public void test1(){
// 获取规则引擎
KieServices kieServices = KieServices.Factory.get();
// 获取连接
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 创建会话1
KieSession kieSession = kieContainer.newKieSession();
// 创建会话2
KieSession kieSession2 = kieContainer.newKieSession();
// 构造订单
Order order =new Order();
order.setOriginalPrice(500.0);
Order order2 =new Order();
order2.setOriginalPrice(100D);
// 添加订单,针对订单进行规则交互计算
kieSession.insert(order);
kieSession2.insert(order2);
// 激活规则引擎
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("book_discount_"));
// AgendaFilter 增加过滤规则
// RuleNameEqualsAgendaFilter 执行名称全匹配的规则
// RuleNameEndsWithAgendaFilter 执行名称以xxx结尾的规则
// RuleNameMatchesAgendaFilter 可以写自己的正则
// RuleNameStartsWithAgendaFilter 执行名称以xxx开头的规则
// RuleNameSerializationAgendaFilter 规则名称序列化代理筛选器
kieSession2.fireAllRules(new RuleNameEqualsAgendaFilter("book_discountA"));
// 关闭会话
kieSession.dispose();
kieSession2.dispose();
System.out.println("订单1的原价格:"+order.getOriginalPrice()+ ",优惠价格:"+order.getRealPrice());
System.out.println("订单2的原价格:"+order.getOriginalPrice()+ ",优惠价格:"+order2.getRealPrice());
}
2.4.2.2 结果
优惠100元
订单优惠了20元
订单1的原价格:500.0,优惠价格:400.0
订单2的原价格:500.0,优惠价格:80.0