zl程序教程

您现在的位置是:首页 >  其他

当前栏目

《Drools7.0.0.Final规则引擎教程》activation-group的多FACT对象详解编程语言

2023-06-13 09:20:44 时间

当我们使用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

15188.html

cjavaxml