《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 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

委托示例(利用委托对不同类型的对象数组排序)

using System; using System.Collections.Generic; using System.Text; namespac...

2049
来自专栏函数式编程语言及工具

Scalaz(4)- typeclass:标准类型-Equal,Order,Show,Enum

  Scalaz是由一堆的typeclass组成。每一个typeclass具备自己特殊的功能。用户可以通过随意多态(ad-hoc polymorphism)把这...

1705
来自专栏程序猿DD

Spring框架中的设计模式(四)​

本文是Spring框架中使用的设计模式第四篇。本文将在此呈现出新的3种模式。一开始,我们会讨论2种结构模式:适配器和装饰器。在第三部分和最后一部分,我们将讨论单...

3386
来自专栏张善友的专栏

.NET 和Java 对象 XML序列化 库WOX

当 .NET 应用程序将对象转换为 XML 文档并存储该 XML。实际上,XML 被用作可移植数据存储机制,因为 .NET 对象被转换为 XML,然后又从 XM...

1925
来自专栏JAVA高级架构

组合模式(Composite)

702
来自专栏斑斓

基于Scala Trait的设计模式

在《作为Scala语法糖的设计模式》中,我重点介绍了那些已经融入Scala语法的设计模式。今天要介绍的两个设计模式,则主要与Scala的trait有关。 Dec...

3225
来自专栏angularejs学习篇

关于c#中委托使用小结

  委托对与我们编程人员来说,一点都不陌生,在实际工作过程中,或多或少都应该是接触过

831
来自专栏java技术学习之道

最通俗易懂的java注解讲解

1063
来自专栏大内老A

依赖注入[2]: 基于IoC的设计模式

正如我们在《控制反转》提到过的,很多人将IoC理解为一种“面向对象的设计模式”,实际上IoC自身不仅与面向对象没有必然的联系,它也算不上是一种设计模式。一般来讲...

773
来自专栏java技术学习之道

Collections.synchronizedMap()、ConcurrentHashMap、Hashtable之间的区别

1274

扫码关注云+社区