drools规则引擎

引入规则引擎背景

现状

在目前的很多行业应用中,如银行、保险、互联网金融等领域,存在着大量的业务规则,这些业务规则有如下的特点:

业务规则数量繁多、非常复杂、且规则处于不断的更新变化中

现有系统的很多做法是将业务规则绑定在程序代码中。

 

存在的问题

当业务规则变更时,对应的代码也得更改,即使每次小的变更都需要经历开发、测试验证上线等过程,变更的成本比较大。

长时间系统变得越来越难以维护。

系统僵化,新需求插入困难。

新需求上线周期较长 。

 

什么是规则引擎

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

  • 规则引擎的核心就是获取knowledge(知识)
  • 应用knowledge到特定的数据上(fact)
  • 使用 “production rules(产生式规则)” IF <conditions> THEN <actions> Rule表达逻辑(任何逻辑都可以用这种方式表达)

 

引入规则引擎好处

实现业务逻辑与业务规则的分离,实现业务规则的集中管理。

可以动态修改业务规则,从而快速响应需求变更。

使业务人员也可以参与编辑、维护系统的业务规则。

使用规则引擎提供的规则编辑工具,使复杂的业务规则实现变得的简单。

  • Rules技术提供了一种新的方式用于创建业务应用系统,通过“声明式”的rule语言写业务逻辑,而不是传统的程序语言
  • Rule engine非常适合解决复杂问题,且在没有更好的其他
  • Rule engine非常适合用来表述业务逻辑

 

什么是规则?

  • 一个rule由conditions,和actions组成。当所有的conditions匹配,rule可能“fire”  Conditions即LHS(left hand side)
  • Actions即RHS(right hand side或者consequence)
  • Rule操纵应用程序中的数据( fact )

 

术语:

  • Rule engines(比如Drools)使用正向或者反向链(或者混合使用)
  • 正向链从事实到结论的推理。rule在LHS conditions匹配的时候执行。Actions可以改变facts,并可能导致新rule被fire。
  • 反向链指则是从假设,即要证明的结论,到事实的推理

 

推理引擎:

  • 规则系统的大脑实际上就是一个推理引擎,用于匹配facts和rules
  • 推理引擎将事实、数据与产生式规则进行匹配(模式匹配),以推出结论
  • 当匹配被找到,rule actions被fire
  • Actions—经常会改变facts的状态,或者在应用上执行一些“外部”action

正向链

正向链接是一个非常强大的概念,它使原子规则能够组合成规则集,而无需定义规则间的依赖性,甚至不必知道这些依赖性。但是,在某些情况下,规则编写者可能希望能够对链接行为提供更多控制,尤其是能够限制发生的链接。这使规则建模器能够做到以下几点:

  • 限制规则的重复执行,从而避免得到不正确的结果。
  • 提高性能。
  • 防止出现失控循环。

 

工作原理

将用户编写的规则文件(*.drl) 通过工具类加载、编译、打成jar包后,加入到指定的地方(一般是和规则引擎打交道的会话session )供规则引擎去调用和执行。

 

实例准备:

添加pom依赖

<!--规则引擎 drools--> 

<dependency> 

<groupId>org.drools</groupId>

<artifactId>drools-core</artifactId>

<version>5.5.0.Final</version>

</dependency> 

<dependency>

<groupId>org.drools</groupId>

<artifactId>drools-compiler</artifactId>

<version>5.5.0.Final</version> 

</dependency>

 

编写实体类

public class Customer {
    //姓名
    private String name;
    //年龄
    private int age;
    //性别
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}

 

编写规则文件(*.drl)

import Customer;//导入实体类,导入写法与Java文件相同
rule "one" //规则名称,不可出现重复规则名 属性块no-loop true //执行一次后,是否能被再次激活salience 1 //优先级别
when //条件块
#eval(true); //匹配结果 
$customer:Customer(age > 30);
 then //结果块 
System.out.println("age>30岁的人:"+ $customer.getName());
 end 
rule 
"second"no-loop true //执行一次后,是否能被再次激活salience 2 //优先级别 
when 
$customer:Customer(sex == "男",age > 25); 
then 
System.out.println("性别为男性且年龄大于25岁的人:"+ $customer.getName()); 
end

 

编写Java测试类

//drl文件路径 
String filePath = "test.drl"; 
//读取drl文件路径 
final Reader source = new FileReader(filePath); 
final PackageBuilder builder = new PackageBuilder();
 builder.addPackageFromDrl(source); 
if (builder.hasErrors()) { 
System.out.println("规则脚本存在错误:" + builder.getErrors().toString()); } //注意这的package不是JDK中lang包下的package而是drools中的 
final Package pkg = builder.getPackage(); //初始化规则库 
final RuleBase ruleBase = RuleBaseFactory.newRuleBase(); 
Package[] packages = ruleBase.getPackages(); 
for (Package p : packages) { 
ruleBase.removePackage(p.getName()); 
} ruleBase.addPackage(pkg); 
final StatefulSession session = ruleBase.newStatefulSession();

//实体类调用写法
Customer customer = new Customer("项羽",31,"男");

session.insert(customer); //调用drl文件中的rule进行判断并返回结果 
session.fireAllRules(new AgendaFilter() { 
public boolean accept(Activation activation) { 
return !activation.getRule().getName().contains("_test");
} 
}
);

//进行规则处理并进行结果返回 
session.dispose();

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值