Drools Fact 对象详解
一、Drools 简介
Drools(JBoss Rules )是一个基于 Java 的开源业务规则引擎,具有易于访问企业策略、易于调整以及易于管理的特点,符合业内标准,速度快、效率高。它可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效。
二、Fact 对象的定义
在 Drools 规则引擎中,Fact 对象是指将一个普通的 JavaBean 对象插入到规则引擎的 WorkingMemory 当中的对象。它是规则与应用系统数据交互的桥梁和通道,规则可以对 Fact 对象进行任意的读写操作。
2.1 本质
Fact 对象本质上是一个普通的 JavaBean,通常是具有 getter 和 setter 方法的 POJO 对象,规则中可以对当前的对象进行任何的读写操作,调用该对象提供的方法。当一个 JavaBean 插入到 WorkingMemory(内存储存)中,规则使用的是原有对象的引用,规则通过对 fact 对象的读写,实现对应用数据的读写。
2.2 作用
Fact 对象承担着将规则当中要用到的业务数据从应用当中传入进来的作用。规则在进行计算时需要的应用系统数据设置在 Fact 对象当中,这样规则就可以通过对 Fact 对象数据的读写实现对应用数据的读写操作。
三、Fact 对象的使用
3.1 插入 Fact 对象
在使用 Drools 时,需要将 Fact 对象插入到规则引擎的 WorkingMemory 中,规则引擎会根据规则条件对插入的 Fact 对象进行匹配。以下是一个简单的示例代码:
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
// 定义一个简单的 Fact 对象类
class Customer {
private String name;
private int age;
private boolean VIP;
// getters and setters
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 boolean isVIP() {
return VIP;
}
public void setVIP(boolean VIP) {
this.VIP = VIP;
}
}
public class DroolsExample {
public static void main(String[] args) {
// 创建 KieServices 实例
KieServices kieServices = KieServices.Factory.get();
// 创建 KieContainer 实例,加载规则文件
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 创建 KieSession 实例
KieSession kieSession = kieContainer.newKieSession();
// 创建 Fact 对象
Customer customerFact = new Customer();
customerFact.setName("John");
customerFact.setAge(30);
customerFact.setVIP(true);
// 插入 Fact 对象
kieSession.insert(customerFact);
// 触发规则执行
kieSession.fireAllRules();
// 关闭 KieSession
kieSession.dispose();
}
}
3.2 规则中使用 Fact 对象
在规则文件中,可以对 Fact 对象进行读写操作。以下是一个简单的规则文件示例:
package com.drools.demo
import com.drools.demo.Customer;
rule "Check VIP Customer"
when
$customer: Customer(age > 25, VIP == true)
then
System.out.println($customer.getName() + " is a VIP customer over 25 years old.");
end
在这个规则中,when 部分是规则的条件部分,通过 Customer(age > 25, VIP == true) 来匹配符合条件的 Fact 对象;then 部分是规则的结果部分,当条件满足时,会执行相应的操作,这里是打印一条信息。
四、Fact 对象的特性
4.1 引用传递
Fact 对象不是对原来的 JavaBean 对象进行 Clone,而是使用传入的 JavaBean 对象的引用。这意味着规则对 Fact 对象的修改会直接影响到原 JavaBean 对象。
4.2 动态操作
在规则中,可以动态的往当前 WorkingMemory 中插入、删除新的 Fact 对象。例如,在规则的 then 部分可以使用 insert 方法插入新的 Fact 对象,使用 retract 方法删除 Fact 对象。
4.3 匹配机制
当 Fact 对象插入到 WorkingMemory 当中后,会与当前 WorkingMemory 当中所有的规则进行匹配,同时返回一个 FactHandler 对象。FactHandler 对象是插入到 WorkingMemory 当中 Fact 对象的引用句柄,通过 FactHandler 对象可以实现对 Fact 对象的删除及修改等操作。
五、Fact 对象的 Equality Modes
在 Drools 中,Fact 对象存在两种 Equality Modes:Identity 模式和 Equality 模式。
5.1 Identity 模式
这是默认的情况。Drools 引擎使用 IdentityHashMap 保存所有插入到工作内存中的 Fact 对象。对于每次插入一个新的对象,则会返回一个新的 FactHandle 对象。如果是重复插入对象,则返回已经存在的 FactHandle 对象。
5.2 Equality 模式
Drools 引擎使用 HashMap 保存所有插入到工作内存中的 Fact 对象。在这种模式下,如果向 Drools 中插入一个新的对象,只有这个对象不存在(根据对象的 hashcode 和 equals 判断)才会返回一个新的 FactHandle,否则返回已经存在的 FactHandle 对象。
5.3 设置方式
可以通过 kmodule.xml 配置文件来设置 Fact 对象的 Equality 行为,示例如下:
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="kbase-identity" packages="rules" default="false" equalsBehavior="identity">
<ksession name="ksession-01" default="false" type="stateful"/>
</kbase>
<kbase name="kbase-equality" packages="rules" default="false" equalsBehavior="equality">
<ksession name="ksession-02" default="false" type="stateful"/>
</kbase>
</kmodule>
六、总结
Fact 对象是 Drools 规则引擎中非常重要的概念,它是规则与应用系统数据交互的关键。通过将业务数据封装在 Fact 对象中,并插入到规则引擎的 WorkingMemory 中,规则引擎可以根据规则条件对 Fact 对象进行匹配和处理,从而实现复杂的业务逻辑。同时,了解 Fact 对象的特性和 Equality Modes 可以帮助我们更好地使用 Drools 规则引擎。", "append": false, "file_name": "drools_fact对象详解.md" } } ]