规则引擎—Drools 语法第一天[学习笔记]

news/2024/11/17 14:47:37/

1.为什么要用规则引擎?

eg:商场商品打折(逻辑与规则如下表)

规则编号购买总金额折扣
1total<1000.9
2100<= total <5000.8
3total>=5000.7

     正常思维如何实现以上逻辑?无非就是if-else分支来判断。

//伪代码

if(total < 100) {
    total *= 0.9;
}else if(total < 500) {
    total *= 0.8;
}else {
    total *= 0.7;
}

此逻辑是通过java代码方式实现的,但存在问题:

硬编码实现业务规则难以维护,难以应对变化,业务规则发生变化需要修改java代码,重启服务才能生效,此操作过于麻烦。

并且 每个节日 打折方式不同,我们不可能每次都去改java代码,并且重启服务器。所以规则引擎就可以解决我们这样的问题。

2.规则引擎 

简介:

       规则引擎,全称为业务规则管理系统,由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。在Java中,大多数流行的规则引擎都实现JSR94。

        他并不是一种具体的技术框架,而是指一类系统,及业务规则系统。比如:drools、ILog等。

优点:

  • 简化系统架构,优化应用
  • 提高系统的可维护性
  • 减少编写“硬代码”业务规则的成本和风险
  • 应付特殊状况,即客户一开始没有提到要将业务逻辑考虑在内
  • 过将规则引擎分开,它提供了更大的可重用性。

应用场景: 

  • 流程分支非常复杂,规则变量庞大
  • 有不确定性的需求,变更频率较高
  • 需要快速做出响应和决策
  • 规则变更期望脱离于开发人员,脱离coding

3.Drools介绍

 定义:drools是一款由JBoss组织提供的基于Java语言开发的开源规则引擎,可以将复杂且多变的业务规则从硬编码中解放出来,以规则脚本的形式存放在文件或特定的存储介质中(例如存放在数据库中),使得业务规则的变更不需要修改项目代码、重启服务器就可以在线上环境立即生效。

在项目中使用Drools,可以直接在IDEA工具中下载Drools插件。

使用:

①单独使用,在pom.xml文件中

//添加依赖
<dependency><groupId>org.drools</groupId><artifactId>drools-compiler</artifactId><version>7.6.0.Final</version>
</dependency>

也可以集成spring、SpringBoot框架使用,之后会说.......

    drools API 开发步骤: 

      ①获取KieServices

      ②获取KieContainer

      ③获取KieSession

      ④Insert fact(事实对象,接收数据的对象实体类)

      ⑤触发规则 fireAllrules()

      ⑥关闭KieSession

4.具体入门案例:

业务场景:消费者在商场消费,优惠折扣如下表:

规则编号购买总金额折扣
1total<300不打折
2300<= total <5000.9
3500<=total<8000.8
4total>=8000.7

开发实现 :

①创建maven项目,添加依赖

<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>

② 在resource文件夹下META-INF中创建kmoudle.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>

 ③创建实体类Goods 创建的对象相当于事实对象。

package com.simia.drools.entity;
​
/*** 商品*/
public class Goods {private String name;private Double originalPrice;//商品原始价格,即优惠前价格private Double realPrice;//商品真实价格,即优惠后价格
​public String toString() {return "Goods{" +"name=" + name +", originalPrice=" + originalPrice +", realPrice=" + realPrice +'}';}public String getName() {return name;}
​public void setName(String name) {this.name = name;}
​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;}
}

fact对象是用来接收数据进入规则引擎与规则匹配进行相对应业务的。

 ④编写规则文件(在resource->rules->goodsDiscount.drl)

//商品优惠规则
package good.discount
import com.simia.drools.entity.Goods
​
//规则一:所购总价在300元以下的没有优惠
rule "good_discount_1"when$order:Order(originalPrice < 300)then$order.setRealPrice($order.getOriginalPrice());System.out.println("成功匹配到规则一:所购总价在300元以下的没有优惠");
end
​
//规则二:所购总价在300到500元的打9折
rule "good_discount_2"when$order:Order(originalPrice < 500 && originalPrice >= 300)then$order.setRealPrice($order.getOriginalPrice()*0.9);System.out.println("成功匹配到规则二:所购总价在300到500元的打9折");
end
​
//规则三:所购总价在500到800元的打8折
rule "good_discount_3"when$order:Order(originalPrice <= 300 && originalPrice >= 200)then$order.setRealPrice($order.getOriginalPrice()*0.8);System.out.println("成功匹配到规则三:所购总价在500到800元的打8折");
end
​
//规则四:所购总价在800元以上的打7折
rule "good_discount_4"when$order:Order(originalPrice >= 800)then$order.setRealPrice($order.getOriginalPrice()*0.7);System.out.println("成功匹配到规则四:所购总价在800元以上的打7折");
end

⑤编写单元测试 

@Test
public void test1(){KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();//会话对象,用于和规则引擎交互KieSession kieSession = kieClasspathContainer.newKieSession();
​//构造订单对象,设置原始价格,由规则引擎根据优惠规则计算优惠后的价格Order order = new Order();order.setOriginalPrice(500D);
​//将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配kieSession.insert(order);
​//激活规则引擎,如果规则匹配成功则执行规则kieSession.fireAllRules();//关闭会话kieSession.dispose();
​System.out.println("优惠前原始价格:" + order.getOriginalPrice() +",优惠后价格:" + order.getRealPrice());
}

总结:由此入门案例可以发现drools工具就是来写drl规则文件的,那drl写业务规则和java代码写有什么区别呢?

          drl文件写业务规则,可以不用重新启动服务,就可以直接使用,实现业务规则的动态化管理。业务人员可以像管理数据一样对业务规则进行管理,比如查询、添加、更新、统计、提交业务规则等。而java硬代码达不到。 

5.规则引擎总结 

构成:

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

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

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

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

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

Execution Engine:执行引擎,执行Agenda中被激活的规则。

 规则引擎执行过程:

kie介绍

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

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


http://www.ppmy.cn/news/247654.html

相关文章

绕开500D收费简历制作的关卡

写在前面环境准备开始吧 制作简历获取pdf修修补补结果展示 总结 写在前面 又到了一年一度准备简历的时候了&#xff0c;一个布局优美&#xff0c;样式良好的简历无疑是加分项。但这要实现起来却很难。 大部分人都是在网上随便下载一个简历模板&#xff0c;涂涂改改&#xff…

Paddle进阶实战系列(一):保险文本视觉认知问答

✨写在前面:强烈推荐给大家一个优秀的人工智能学习网站,内容包括人工智能基础、机器学习、深度学习神经网络等,详细介绍各部分概念及实战教程,通俗易懂,非常适合人工智能领域初学者及研究者学习。➡️点击跳转到网站。 保险文本视觉认知问答 1.项目介绍 1.1背景 随着人…

五百丁简历下载的一种方法

为了下载自己在五百丁上的简历&#xff0c; 下面将分享一个油猴脚本&#xff0c;重新实现下载。 思路如下&#xff1a; 调用jQuery.print.js这个包对网页进行打印&#xff0c;将打印出来的PDF保存即可。 代码如下&#xff1a; // UserScript // name 五百丁简历下载 /…

【博客642】relabeling in Prometheus and VictoriaMetrics

如何在Prometheus和VictoriaMetrics中使用relabel relabel function Adding new labelUpdating existing labelRewriting existing labelUpdating metric nameRemoving unneeded labelsRemoving unneeded metricsDropping metrics on certain conditionModifying label names…

史密斯热水器 保养灯亮闪烁

1.就是镁棒快没了。 2.史密斯自己称作智能镁棒&#xff0c;就是外面多一个接线柱。 3.网购一根&#xff0c;原来的比较难拆&#xff0c;锈住了&#xff0c;买瓶去去锈剂,边振动边喷边拆才能拆下。 4.换上新的镁棒后&#xff0c;还是会报保养灯亮闪烁。 5.史密斯保养灯复位&…

反射系数 史密斯圆图

反射系数 |Γ|的值会介在在-1&#xff08;负载短路&#xff0c;Z_L0&#xff09;到1&#xff08;负载开路&#xff0c;Z_L∞&#xff09;之间&#xff0c;而当|Γ|为0时即表示阻抗匹配。 在斯密斯圆图上如何确定负载端的反射系数 负载归一化&#xff0c;Zl/Z0,圆图中找等阻抗图…

ao史密斯定时设置_史密斯热水器定时是设定几小时后加热吗

呼吸的健康是我们都需要重视的事情&#xff0c;一旦呼吸不安全&#xff0c;肯定会对我们的健康造成很大的影响&#xff0c;很多人现在都会在家里面安装一个空气除湿机&#xff0c;提升室内空气的质量&#xff0c;保证呼吸的安全。虽然现在很多人都在使用空气除湿机&#xff0c;…