《Drools7.0.0.Final规则引擎教程》番外实例篇——activation-group的多FACT对象

场景

当我们使用activation-group时,默认会执行优先级最高的一个规则,然后其他规则不再执行,这也是此属性的基本特性。那么,大家是否考虑过这样一个问题,那就是如果在调用fireAllRules方法之前,insert了多个对象,那么应该触发几次规则?

在其他属性的使用时,我们知道,如果插入多个对象,那么如果每个对象都符合同一规则条件就会执行多次,如果部分条件符合规则,就执行部分次。当我们即想使用activation-group的特性,又想实现上面的要求时改如何去做呢?

实例解析

实例一

首先,我们来确认第一个问题,insert多个FACT对象,会触发几次规则。

@Test
    public void testRules() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kieContainer = ks.getKieClasspathContainer();

        KieSession kSession = kieContainer.newKieSession("ksession-rule");
        kSession.getAgenda().getAgendaGroup("foo").setFocus();


        Product p2 = new Product();
        p2.setDiscount(20);
        Product p1 = new Product();
        p1.setDiscount(10);

        kSession.insert(p2);
        kSession.insert(p1);

        int count = kSession.fireAllRules();
        System.out.println("第一次执行命中了" + count + "条规则!");
        kSession.dispose();
    }
package com.rules
import com.secbro.drools.model.Product

 rule "test-activation-group1"
    activation-group "foo"
    when
        $obj : Product()
    then
        System.out.println("test-activation-group1 被触发");
    end

rule "test-activation-group2"
    activation-group "foo"
    salience 1
    when
    $obj : Product()
    then
        System.out.println("test-activation-group2 被触发 discount= " + $obj.getDiscount());
    end

执行的结果如下:

test-activation-group2 被触发 discount= 10
第一次执行命中了1条规则!

很显然,插入了两个FACT对象,只触发了一次规则。

实例二

那么,我们想达到上面说的,如果插入多个对象,每个符合条件的都触发一次,同时一个activation-group组中只触发优先级比较高的。 这就需要我们修改改代码如下:

@Test
    public void testRules() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kieContainer = ks.getKieClasspathContainer();

        KieSession kSession = kieContainer.newKieSession("ksession-rule");
        kSession.getAgenda().getAgendaGroup("foo").setFocus();


        Product p2 = new Product();
        p2.setDiscount(20);
        kSession.insert(p2);
        int count = kSession.fireAllRules();
        System.out.println("第一次执行命中了" + count + "条规则!");

        Product p1 = new Product();
        p1.setDiscount(10);
        kSession.insert(p1);

        count = kSession.fireAllRules();
        System.out.println("第一次执行命中了" + count + "条规则!");
        kSession.dispose();
    }

执行结果:

test-activation-group2 被触发 discount= 20
第一次执行命中了1条规则!
test-activation-group2 被触发 discount= 10
第一次执行命中了1条规则!

像上面这样,每执行一次调用一次fireAllRules就达到了预期的目的。

另外一种方式就是不使用activation-group方法,而采用delete方法。

@Test
    public void testRules() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kieContainer = ks.getKieClasspathContainer();

        KieSession kSession = kieContainer.newKieSession("ksession-rule");
        kSession.getAgenda().getAgendaGroup("foo").setFocus();


        Product p2 = new Product();
        p2.setDiscount(20);
        kSession.insert(p2);

        Product p1 = new Product();
        p1.setDiscount(10);
        kSession.insert(p1);

        int count = kSession.fireAllRules();
        System.out.println("第一次执行命中了" + count + "条规则!");
        kSession.dispose();
    }
package com.rules
import com.secbro.drools.model.Product

 rule "test-activation-group1"
//    activation-group "foo"
    when
        $obj : Product()
    then
        delete($obj)
        System.out.println("test-activation-group1 被触发");
    end

rule "test-activation-group2"
//    activation-group "foo"
    salience 1
    when
    $obj : Product()
    then
        delete($obj)
        System.out.println("test-activation-group2 被触发 discount= " + $obj.getDiscount());
    end

后语

此系列课程持续更新中,QQ群:593177274欢迎大家加入讨论。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

读取txt正则匹配行写入txt

1011
来自专栏一个会写诗的程序员的博客

MD5Utils 简单计算MD5

612
来自专栏大内老A

通过实例模拟ASP.NET MVC的Model绑定的机制:集合+字典

在本系列的前面两篇文章(《简单类型+复杂类型》、《数组》)我们通过创建的实例程序模拟了ASP.NET MVC默认使用的DefaultModelBinder对简单...

2657
来自专栏Spark生态圈

[Spark SQL] 源码解析之Analyzer

Analyzer模块将Unresolved LogicalPlan结合元数据catalog进行绑定,最终转化为Resolved LogicalPlan。跟着代码...

822
来自专栏程序员Gank

iOS-代码规范

利用上周的业余时间把这篇规范整理了出来,我会将这篇规范作为我们iOS团队的代码规范,并且还会根据读者的反馈,项目的实践和研究的深入做不定时更新,还希望各位朋友看...

2002
来自专栏xingoo, 一个梦想做发明家的程序员

汇编语言 手记8

栈有两个基本的操作:入栈和出栈 入栈:将一个新的元素放到栈顶 出栈:从栈顶取出一个元素 栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。 栈的操作规则:...

1785
来自专栏乐百川的学习频道

Java 8 新特性(三)新的日期时间类

老日期类 一说到在Java中处理日期和时间,我们首先想到的肯定是java.util.Date类。确实,由于很多教材和文献都比较老,所以大多数人学习Java的时候...

2055
来自专栏码匠的流水账

聊聊spring cloud gateway的GatewayFilter

本文主要研究一下spring cloud gateway的GatewayFilter

1791
来自专栏Ryan Miao

jackson简单使用,对象转json,json转对象,json转list

添加jackson依赖: // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/ja...

33511
来自专栏程序员维他命

iOS 代码规范

花了一个月的时间结合几篇博客和书籍写了这套 iOS 代码规范(具体参考底部的参考文献部分)。这套代码规范除了有仅适用于 iOS 开发的部分,还有其他的比较通用性...

1112

扫码关注云+社区