深入浅析drools中Fact的equality modes

网友投稿 570 2022-10-05

深入浅析drools中Fact的equality modes

目录一、equality modes介绍1、identity模式2、equality模式二、需求三、如何设置fact对象的equality行为四、编码实现1、项目结构图2、倒入jar包3、编写Person对象4、编写kmodule.xml文件5、编写一个规则文件6、identity模式测试1、编写测试代码2、运行结果7、equality模式测试1、编写测试代码2、运行结果五、结论1、identity模式下2、equality模式下六、完整代码七、参考链接

一、equality modes介绍

在drools中存在如下2种equality modes。

1、identity模式

identity:这是默认的情况。drools引擎使用IdentityHashMap保存所有插入到工作内存中的Fact对象。对于每次插入一个新的对象,则会返回一个新的FactHandle对象。如果是重复插入对象,则返回已经存在的FactHandle对象。

举例:

Person p1 = new Person("zhangsan", 20, "湖北罗田");

Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");

FactHandle factHandle1 = kieSession.insert(p1);

FactHandle factHandle2 = kieSession.insert(p2);

FactHandle factHandle3 = kieSession.insert(p2);

针对以上例子, factHandle1 != factHandle2但是 factHandle2 == factHandle3。即工作内存中会存在2个Person对象。

2、equality模式

equality:drools引擎使用HashMap保存所有插入到工作内存中的Fact对象。在这种模式下,如果向drools中插入一个新的对象,只有这个对象不存在(根据对象的hashcode和equals判断)才会返回一个新的FactHandle否则返回已经存在的FactHandle。

举例:

// 重写了Person对象的hashcode和equals方法

Person p1 = new Person("zhangsan", 20, "湖北罗田");

Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");

FactHandle factHandle1 = kieSession.insert(p1);

FactHandle factHandle2 = kieSession.insert(p2);

FactHandle factHandle3 = kieSession.insert(p2);

针对以上例子, factHandle1 == factHandle2但是 factHandle2 == factHandle3。即工作内存中会存在1个Person对象。

二、需求

我们存在一个Person对象,存在如下3个属性name,age和address,其中重写对象的name和age的hashcode和equals方法。

多次向工作内存中插入对象,看产生的结果。插入同一个对象看获取到的FactHandle对象是否是同一个。

三、如何设置fact对象的equality行为

此处介绍一个通过kmodule.xml配置的方法

通过上方的代码可知是通过配置kbase下的equalsBehavior属性来配置。

其余的配置方法,参考下图:

四、编码实现

1、项目结构图

2、倒入jar包

org.drools

drools-bom

pom

7.69.0.Final

import

org.drools

drools-compiler

org.drools

drools-mvel

ch.qos.logback

logback-classic

1.2.11

3、编写Person对象

public class Person {

private String name;

private Integer age;

private String address;

public Person(String name, Integer age, String address) {

this.name = name;

this.age = age;

this.address = address;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

Person person = (Person) o;

return Objects.equals(name, person.name) && Objects.equals(age, person.age);

}

@Override

public int rMRJTOxnqVhashCode() {

return Objects.hash(name, age);

}

}

注意:此对象需要重写hashcode和equals方法。

4、编写kmodule.xml文件

在此配置文件中,需要在kbase上指定equalsBehavior,用来确定Fact对象的equality modes。

注意:需要看2个equalsBehavior的取值

5、编写一个规则文件

package rules

import com.huan.drools.Person

// 定义规则

rule "rule_01"

when

$p: Person()

then

System.out.println(Thread.currentThread().getName() + " name:"+$p.getName()+" age:"+$p.getAge());

end

规则文件中的内容很简单,只要工作内存中存在Person对象,那么就输出这个对象的name和age的值。

6、identity模式测试

1、编写测试代码

public class DroolsApplication {

public static void main(String[] args) {

equalsBehaviorIdentity();

}

private static void equalsBehaviorIdentity() {

KieServices kieServices = KieServices.get();

KieContainer kieContainer = kieServices.getKieClasspathContainer();

// 注意此处的 ksession-01

KieSession kieSession = kieContainer.newKieSession("ksession-01");

kieSession.addEventListener(new DebugRuleRuntimeEventListener());

Person p1 = new Person("zhangsan", 20, "湖北罗田");

Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");

FactHandle factHandle1 = kieSession.insert(p1);

FactHandle factHandle2 = kieSession.insert(p2);

FactHandle factHandle3 = kieSession.insert(p2);

kieSession.fireAllRules();

kieSession.dispose();

}

}

2、运行结果

具体的解释见上图中的说明。

7、equality模式测试

1、编写测试代码

public class DroolsApplication {

public static void main(String[] args) {

equalsBehaviorEquality();

}

private static void equalsBehaviorEquality() {

KieServices kieServices = KieServices.get();

KieContainer kieContainer = kieServices.getKieClasspathContainer();

KieSession kieSession = kieContainer.newKieSession("ksession-02");

kieSession.addEventListener(new DebugRuleRuntimeEventListener());

Person p1 = new Person("zhangsan", 20, "湖北罗田");

Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");

FactHandle factHandle1 = kieSession.insert(p1);

FactHandle factHandle2 = kieSession.insert(p2);

FactHandle factHandle3 = kieSession.insert(p2);

kieSession.fireAllRules();

kieSession.dispose();

}

}

2、运行结果

五、结论

针对如下代码,看看在不同equality modes下的行为

Person p1 = new Person("zhangsan", 20, "湖北罗田");

Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");

FactHandle factHandle1 = kieSession.insert(p1);

FactHandle factHandle2 = kieSession.insert(p2);

FactHandle factHandle3 = kieSession.insert(p2);

Person对象的hashcode和equals方法进行重写了,根据构造方法的前2个参数。

1、identity模式下

factHandle1 != factHandle2 因为p1和p2是2个不同的对象。factHandle2 == factHandle3 因为是p2重复加入工作内存,这个时候工作内存中已经存在了,所以返回之前关联的FactHandle

2、equality模式下

factHandle1 == factHandle2 == factHandle3 因为这种模式下,是需要根据对象的equals和hashcode方法进行比较,而Person对象重写了这2个方法,所以返回的是同一个。

六、完整代码

https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-fact-equality-modes

七、参考链接

1、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#fact-equality-modes-con_decision-engine

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:简单易懂--适合零基础的微信体验小程序开发教程(微信小程序开发教程--从零开始-简书)
下一篇:codeforces 121E Lucky Array
相关文章

 发表评论

暂时没有评论,来抢沙发吧~