Drools 规则引擎,升职加薪神器,30K 妥妥的

小七学习网,助您升职加薪,遇问题可联系:客服微信【1601371900】 备注:来自网站

面对复杂多变的业务场景,传统的硬编码方式兼职让人奔溃,天天发版本,天天改规则,人力成本损耗巨大。 如何处理这种业务多变的场景呢?建议使用规则引擎 Drools。 废话不多说,我罗列了一下几个要点,大家…

面对复杂多变的业务场景,传统的硬编码方式兼职让人奔溃,天天发版本,天天改规则,人力成本损耗巨大。

如何处理这种业务多变的场景呢?建议使用规则引擎 Drools。

废话不多说,我罗列了一下几个要点,大家一起学习,一起进步。

  1. Drools 初步认识。
  2. 模式匹配算法:Rete 算法必知必会。
  3. Drools 规则以及语法解释。
  4. 促销场景如何使用 Drools 引擎快速简单解决规则问题?


Drools 初步认识

什么是 Drools

一款基于 Java 的开源规则引擎。它可以将复杂的业务决策从程序中分离出来。减少硬编码业务规则带来的风险和运维成本。它的核心算法是规则快速匹配算法 Rete。 适用于银行、保险、零售、游戏等业务规则灵活多变的场景。

Drools 规则引擎的组成部分

Drools 由三个部分组成:工作内存 Working Memory、规则库 Rule Base、推理引擎 Inference Engine。

其中,推理引擎再由匹配器 Pattern Matcher、议程 Agenda、执行引擎 Execution Engine 三个部分组成。 如下图展示:

drools 组成部分

工作内存

工作内存用来存储待匹配的业务数据,规则引擎会从工作内存中获取业务数据,再和规则文件进行匹配。例如:商品 A、售价 100 元,这样类似的数据。

规则库 Rule Base

用来存放规则文件中定义的规则的地方,叫规则库。

匹配器 Pattern Matcher

匹配器,将规则库中的规则和 Fact 事实对象进行匹配的工具。再将匹配成功的规则将存入议程中。

议程 Agenda

议程,存放匹配器匹配成功后激活的业务规则。

执行引擎 Execution Engine

负责执行议程中被激活的业务规则。

事实 fact

普通的 Java 对象加载到工作内存后,我们就称它为一个事实,例如:商品 A,就是一个事实。

Drools 的工作原理

将提交的数据对象和规则进行匹配对比,激活符合规则的业务规则:

  • 将规则存入规则库,将业务对象存入工作内存。
  • 规则引擎加载业务规则和业务对象并进行匹配。
  • 将匹配成功的规则加入到议程中,并激活规则。
  • 执行引擎执行已经激活的规则。

涉及概念解释

  • KIE:全称 Knowledge IS Everything。
  • KIE:业务自动化综合解决方案,包含 OptaPlanner、Drools、UberFire、jBPM,Drools 是它的一个组成部分。
  • kieServices:一个线程安全的单例对象,是规则引擎其他服务的中心。
  • KieContainer:规则容器。
  • KieSession:规则引擎会话,可以存入 bean 对象。

Rete 算法

什么是 Rete 算法

Rete 算法是一种前向规则快速匹配算法,将事实与规则进行匹配,其匹配速度与规则数目无关。它的核心思想是用分离的匹配项构造匹配网络,缓存中间结果,通过空间换时间。

它有两个思想:规则编译(rule compilation)和运行时执行(runtime execution)。规则编译是指根据规则集生成高效推理网络的过程。

Rete 算法涉及的概念

Fact

对象之间及对象属性之间的关系。

Rule

推理判断的规则,可以理解为 ifelse。一个规则的 if 部分叫 LHS,then 部分叫 RHS(right hand side)。

Module 模式

if 条件语句。多个 if 条件可以组合成为一个更大的条件。模式是指最小的原子条件。

Rete 算法三个阶段

匹配 match、选择 select 和执行 actcycle:

  • 将需要处理的事实 facts 导入到集合当中。
  • 迭代选择 facts 去醒醒匹配处理,如果没有 fact 则终止运行。
  • 将满足要求的规则加入到议程当中激活,安排执行器去执行规则。

Drools 规则以及语法解释

连接符

连接符一共有三种,&& 和 ||,且和或;另外,逗号 , 和且是一样的效果,但是不能同时出现。

且连接符

$product:Product(price < 100 && price >= 50)$product:Product(price < 100 , price >= 50)

或连接符

$product:Product(price < 100 || price >= 50)

类型比较操作符

小于 <、大于 >、等于 ==、不等于 !=、大于等于 >=、小于等于 <=,这些和 Java 的符号是一样的。

rule \"discount_6\"    when        $product:Product(price >= 600)    then        $product.setDiscountPrice($product.getPrice() - 100);        System.out.println(\"商品的价格大于 600,则减 100 块钱。\");end

contains not contains 包含不包含

是否包含或者不包含某个字符串,如下:

rule \"discount_7\"    when        $product:Product(productName contains \"鞋子\")    then        System.out.println(\"我这个商品是鞋子。\");end

memberOf not memberOf

用于判断对象的某个字段是否存在一个集合中:

rule \"discount_8\"    when        $product:Product(productName memberOf \"鞋子,衣服,裤子\")    then        System.out.println(\"商品名是否是其中之一\");end

matches not matches

matches 用于匹配正则表达式:

rule \"discount_9\"    when        $product:Product(productName matches \"鞋.*\");    then        System.out.println(\"正则表达式匹配\"+$product.getProductName());end

规则文件语法解析以及执行流程

规则文件语法
  • package:包名,包路径,逻辑路径
  • rule:规则名,规则名不能重复
  • import:导入外部变量,类
  • globals:全局变量
  • functions:函数
  • queries:查询
  • rule:规则
when      条件——也叫作规则的 LHS  then      结果——也叫作规则的 RHS  end
DRL 解析执行流程

Drools 规则在 Java 应用程序上运行,规则引擎会将规则转换成 执行树,按照树的结构依次执行。

例如如下的图片:

条件解析过程

促销场景使用 Drools 引擎匹配规则的 Demo

电商促销场景下,各种各样的活动、各种各样的优惠规则,再加上商品属性,非常适合使用 Drools。

下面,我们假设一个业务场景,我们有一个商品,名称为鞋子。它的价格在不同情况下不一样。现在用户购买这个商品,我们需要给用户一个满减折扣。例如:满 50 减 10,满 100 减 20,满 500 减 100。

首先,Demo 项目目录如下:

项目目录

添加 POM 依赖

<dependency>    <groupId>org.drools</groupId>    <artifactId>drools-core</artifactId>    <version>7.14.0.Final</version></dependency><dependency>    <groupId>org.kie</groupId>    <artifactId>kie-spring</artifactId>    <version>7.14.0.Final</version></dependency>

创建商品实体类

设置商品名、商品价格、打折优惠的属性。

@Datapublic class Product {    private String productName;    private Double price;    private Double discountPrice;}

配置 Drools 配置文件

配置文件需要放置在 resources/META-INF/ 目录下。

<?xml version=\"1.0\" encoding=\"UTF-8\" ?><kmodule xmlns=\"http://www.drools.org/xsd/kmodule\">    <kbase name=\"base1\" packages=\"rules\" default=\"true\">        <ksession name=\"ksession-rule\" default=\"true\"/>    </kbase></kmodule>

创建 Drools 规则文件

规则文件需要放置在 resources/rules/ 目录下:

//优惠券满减规则package product.discountimport com.drools.demo.entity.Product//一:商品的价格低于 50 元,则没有满减。rule \"discount_1\"    when        $product:Product(price < 50)    then        $product.setDiscountPrice($product.getPrice());        System.out.println(\"商品的价格低于 50 元,则没有满减!\");end//二:商品的价格低于在 50 元到 100 元之间,则减 10 块钱。rule \"discount_2\"    when        $product:Product(price < 100 && price >= 50)    then        $product.setDiscountPrice($product.getPrice() - 10);        System.out.println(\"商品的价格低于在 50 元到 100 元之间:商品减少 10 块钱。\");end//三:商品的价格低于在 100 元到 200 元之间,则减 20 块钱。rule \"discount_3\"    when        $product:Product(price < 200 && price >= 100)    then        $product.setDiscountPrice($product.getPrice() - 20);        System.out.println(\"商品的价格低于在 100 元到 200 元之间:商品减少 20 块钱\");end//四:商品的价格低于在 200 元到 500 元之间,则减 30 块钱。rule \"discount_4\"    when        $product:Product(price < 500 && price >= 200)    then        $product.setDiscountPrice($product.getPrice() - 30);        System.out.println(\"商品的价格低于在 200 元到 500 元之间,则减 30 块钱\");end//五:商品的价格大于 500,则减 100 块钱。rule \"discount_5\"    when        $product:Product(price >= 500)    then        $product.setDiscountPrice($product.getPrice() - 90);        System.out.println(\"商品的价格大于 500,则减 90 块钱。\");endrule \"discount_6\"    when        $product:Product(price >= 600)    then        $product.setDiscountPrice($product.getPrice() - 100);        System.out.println(\"商品的价格大于 600,则减 100 块钱。\");endrule \"discount_7\"    when        $product:Product(productName contains \"鞋子\")    then        System.out.println(\"我这个商品是鞋子。\");endrule \"discount_8\"    when        $product:Product(productName memberOf \"鞋子,衣服,裤子\")    then        System.out.println(\"商品名是否是其中之一\");endrule \"discount_9\"    when        $product:Product(productName matches \"鞋.*\");    then        System.out.println(\"正则表达式匹配\"+$product.getProductName());end

创建测试类

@Testpublic void test1() {    KieServices kieServices = KieServices.Factory.get();    KieContainer kieContainer = kieServices.newKieClasspathContainer();    KieSession session = kieContainer.newKieSession();    Product product = new Product();    product.setProductName(\"鞋子\");    product.setPrice(20d);    session.insert(product);    int count = session.fireAllRules();    System.out.println(\"规则的数量:\"+count);    session.dispose();    System.out.println(product.getProductName()+\"-满减后的价格:\" + product.getDiscountPrice());}

测试类运行以后效果如下:当 product 商品传入不同的属性,系统就会自动匹配不同的规则进行输出。

商品的价格低于 50 元,则没有满减!我这个商品是鞋子。商品名是否是其中之一正则表达式匹配鞋子规则的数量:5鞋子-满减后的价格:20.0

总结

  • Drools 将业务规则,统一放置在了配置文件里面,所以对规则的管理变得非常清晰和方便。避免了直接在业务代码里面修改的时候,漏改或者改错的情况。好处显而易见。
  • Drools 的规则语法也和 Java 非常相似,对于 Java 程序员来说,非常容易上手。
  • 在必要的时候,我们还可以解析 DRL 规则文件,将元素存在数据库当中,当需要使用的时候,从数据库读取出来,再通过 FreeMarker 模板的方式来生成 DRL 文件。

小七学习网,助您升职加薪,遇问题可联系:客服微信【1601371900】 备注:来自网站

免责声明: 1、本站信息来自网络,版权争议与本站无关 2、本站所有主题由该帖子作者发表,该帖子作者与本站享有帖子相关版权 3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和本站的同意 4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责 5、用户所发布的一切软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。 6、您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 7、请支持正版软件、得到更好的正版服务。 8、如有侵权请立即告知本站(邮箱:1099252741@qq.com,备用微信:1099252741),本站将及时予与删除 9、本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章和视频仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。