Drools规则引擎应⽤看这⼀篇就够了1 .场景
1.1需求
商城系统消费赠送积分
100元以下, 不加分
100元-500元加100分
500元-1000元加500分
1000元以上加1000分
......
1.2传统做法
if (Amout() <= 100){
order.setScore(0);
addScore(order);
}else Amout() > 100 && Amout() <= 500){
order.setScore(100);
addScore(order);
}else Amout() > 500 && Amout() <= 1000){
order.setScore(500);
addScore(order);
}else{
order.setScore(1000);
addScore(order);
}
interface Strategy {
addScore(int num1,int num2);
}
class Strategy1 {
addScore(int num1);
}
......................
interface StrategyN {
addScore(int num1);
}
class Environment {
private Strategy strategy;
public Environment(Strategy strategy) {
this.strategy = strategy;
}
public int addScore(int num1) {
return strategy.addScore(num1);
}
}
以上解决⽅法问题思考:
如果需求变更,积分层次结构增加,积分⽐例调整?
数据库?
遇到的问题瓶颈:
第⼀,我们要简化if else结构,让业务逻辑和数据分离!
第⼆,分离出的业务逻辑必须要易于编写,⾄少单独编写这些业务逻辑,要⽐写代码快!
第三,分离出的业务逻辑必须要⽐原来的代码更容易读懂!
第四,分离出的业务逻辑必须⽐原来的易于维护,⾄少改动这些逻辑,应⽤程序不⽤重启!
2.是什么
2.1概念
规则引擎由发展⽽来,是⼀种嵌⼊在应⽤程序中的组件,实现了将业务决策从应⽤程序代码中分离出来,
并使⽤预定义的语义模块编写业务决策。接受数据输⼊,解释业务规则,并根据业务规则做出业务决策
需要注意的是规则引擎并不是⼀个具体的技术框架,⽽是指的⼀类系统,即业务规则管理系统。⽬前市⾯上具体的规则引擎产品有:drools、VisualRules、iLog等
在很多企业的 IT 业务系统中,经常会有⼤量的业务规则配置,⽽且随着企业管理者的决策变化,这些业务规则也会随之发⽣更改。为了适应这样的需求,我们的 IT 业务系统应该能快速且低成本的更新。适应这样的需求,⼀般的作法是将业务规则的配置单独拿出来,使之与业务系统保持低耦合。⽬前,实现这样的功能的程序,已经被开发成为规则引擎。
2.2 起源
2.3 原理--基于 rete 算法的规则引擎
在 AI 领域,产⽣式系统是⼀个很重要的理论,产⽣式推理分为正向推理和逆向推理产⽣式,其规则的⼀般形式是:IF 条件 THEN 操作。rete 算法是实现产⽣式系统中正向推理的⾼效模式匹配算法,通过形成⼀个 rete ⽹络进⾏模式匹配,利⽤基于规则的系统的时间冗余性和结构相似性特征,提⾼系统模式匹配效率
正向推理(Forward-Chaining)和反向推理(Backward-Chaining)
(1)正向推理也叫演绎法,由事实驱动,从⼀个初始的事实出发,不断地从应⽤规则得出结论。⾸先在候选队列中选择⼀条规则作为启⽤规则进⾏推理,记录其结论作为下⼀步推理的证据。如此重复这个过程,直到再⽆可⽤规则可被选⽤或者求得了所要求的解为⽌。
(2)反向推理也叫归纳法,由⽬标驱动,⾸先提出某个假设,然后寻⽀持该假设的证据,若所需的证据都能到,说明原假设是正确的,若⽆论如何都不到所需要的证据,则说明原假设不成⽴,此时需要另作新的假设。
Rete 算法最初是由卡内基梅隆⼤学的 Charles L.Forgy 博⼠在 1974 年发表的论⽂中所阐述的算法 , 该算法提供了专家系统的⼀个⾼效实现。⾃ Rete 算法提出以后 , 它就被⽤到⼀些⼤型的规则系统中 , 像 ILog、Jess、JBoss Rules 等都是基于 RETE 算法的规则引擎。
Rete 在拉丁语中译为”net”,即⽹络。Rete 匹配算法是⼀种进⾏⼤量模式集合和⼤量对象集合间⽐较的⾼效⽅法,通过⽹络筛选的⽅法出所有匹配各个模式的对象和规则。
其核⼼思想是将分离的匹配项根据内容动态构造匹配树,以达到显著降低计算量的效果。Rete 算法可以
被分为两个部分:规则编译和规则执⾏。当 Rete 算法进⾏事实的断⾔时,包含三个阶段:匹配、选择和执⾏,称做 match-select-act cycle。
2.4 规则引擎应⽤场景
业务领域⽰例
财务决策贷款发放,征信系统
库存管理及时的供应链路
票价计算航空,传播,⽕车及其他公共汽车运输
⽣产采购系统产品原材料采购管理
风控系统风控规则计算
促销平台系统满减,打折,加价购
2.5 Drools 介绍
Drools 具有⼀个易于访问企业策略、易于调整以及易于管理的开源业务,符合业内标准,速度快、效率⾼。业务分析师或审核⼈员可以利⽤它轻松查看业务规则,从⽽检验已编码的规则是否执⾏了所需的业务规则。其前⾝是 Codehaus 的⼀个开源项⽬叫 Drools,后被纳⼊ JBoss 门下,更名为 JBoss Rules,成为了 JBoss 应⽤服务器的规则引擎。
Drools 被分为两个主要的部分:编译和运⾏时。编译是将规则描述⽂件按ANTLR 3 语法进⾏解析,对语法进⾏正确性的检查,然后产⽣⼀种中间结构“descr”,descr ⽤AST 来描述规则。⽬前,Drools ⽀持四种规则描述⽂件,分别是:drl ⽂件、 xls ⽂件、brl ⽂件和 dsl ⽂件,其中,常⽤的描述⽂件是 drl ⽂件和 xls ⽂件,⽽ xls ⽂件更易于维护,更直观,更为被业务⼈员所理解。运⾏时是将 AST传到 PackageBuilder,由 PackagBuilder来产⽣ RuleBase,它包含了⼀个或多个 Package 对象。
3 .消费赠送积分案例
上图为实际⽤法:
3.1 第⼀步:创建⼯程,引⼊jar
由于当前java开发,普通使⽤springboot ,本课程以springboot为基本框架演⽰
jar 依赖,注意,排除spring相关依赖
<!-- 规则引擎 -->
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>
<version>${drools.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
3.2 创建 drools ⾃动配置类
drools 在spring 或者springboot中⽤法⼀样,其实就是创建好⼀些bean
package com.fig;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.*;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.kie.spring.KModuleBeanFactoryPostProcessor;
import org.springframework.dition.ConditionalOnMissingBean;
import t.annotation.Bean;
import t.annotation.Configuration;
import io.Resource;
import io.support.PathMatchingResourcePatternResolver;
import io.support.ResourcePatternResolver;
import java.io.IOException;
/**
* <p> 规则引擎⾃动配置类 </p>
* @author ityml
* @date 2019/9/10 11:20
*/
@Configuration
public class DroolsAutoConfiguration {
private static final String RULES_PATH = "rules/";
private KieServices getKieServices() {
return ();
}
@Bean
@ConditionalOnMissingBean(KieFileSystem.class)
public KieFileSystem kieFileSystem() throws IOException {
KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
for (Resource file : getRuleFiles()) {
kieFileSystem.wClassPathResource(RULES_PATH + Filename(), "UTF-8")); }
return kieFileSystem;
}
private Resource[] getRuleFiles() throws IOException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
Resources("classpath*:" + RULES_PATH + "**/*.*");
}
@Bean
@ConditionalOnMissingBean(KieContainer.class)
public KieContainer kieContainer() throws IOException {
final KieRepository kieRepository = getKieServices().getRepository();
kieRepository.addKieModule(() -> DefaultReleaseId());
KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
KieContainer kieContainer = getKieServices().DefaultReleaseId());
return kieContainer;
}
@Bean
@ConditionalOnMissingBean(KieBase.class)spring framework是什么框架的
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}
}
3.2订单实体类
@Data
@Accessors(chain = true)
public class Order {
/**
* 订单原价⾦额
*/
private int price;
/
**
*下单⼈
*/
private User user;
/**
*积分
*/
private int score;
/**
* 下单⽇期
*/
private Date bookingDate;
}
3.3规则引擎⽂件package rules
import com.ity.Order
rule "zero"
no-loop true
lock-on-active true
salience 1
when
$s : Order(amout <= 100)
then
$s.setScore(0);
update($s);
end
rule "add100"
no-loop true
lock-on-active true
salience 1
when
$s : Order(amout > 100 && amout <= 500)
then
$s.setScore(100);
update($s);
end
rule "add500"
no-loop true
lock-on-active true
salience 1
when
$s : Order(amout > 500 && amout <= 1000)
then
$s.setScore(500);
update($s);
end
rule "add1000"
no-loop true
lock-on-active true
salience 1
when
$s : Order(amout > 1000)
then
$s.setScore(1000);
update($s);
end
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论