java - Drools 中的工作内存和对象插入行为

标签 java drools business-rules

我是 Drools 的新手,已经阅读了一些文档和教程,当然,我的问题有一个简单的解决方案。 我仅使用规则文件和类 Counter,如下所示。环境是:Wintel JDK 1.7(71),DROOLS 6.1.0

public class DroolsInsertionTester {
private Logger log = Logger.getLogger(this.getClass().getName());

private KieSession getNewStatefullKIESession (){
   KieContainer kContainer = KieServices.Factory.get().getKieClasspathContainer();

   KieSession kSession = kContainer.newKieSession("test");
   return kSession;
}
public static void main(String[] args) {
    // TODO Auto-generated method stub
    DroolsInsertionTester tester =  new DroolsInsertionTester();
    tester.test(); 


}

private void test() {
    KieSession kSession = getNewStatefullKIESession();

    Counter cnt1 = new Counter(1);
    Counter cnt2 = new Counter(2);

    FactHandle fact1, fact2;

    // STEP 1
    fact1 = kSession.insert(cnt1);
    kSession.fireAllRules();

    // STEP 2
    fact2 = kSession.insert(cnt2);
    kSession.fireAllRules();
}

 public class Counter {
      public int count;
      public Counter (int cnt){
           this.count = cnt;
 }

有一个规则

 rule "Counter shower 1" 
    when $Counter  : Counter() 
 then 
    System.out.println("Counter there (1) : " + $Counter.count);
 end

 rule "Counter shower 2" 
when 
    $Counter  : Counter()  
    accumulate (Counter() ; $cnt : count())
then 
    System.out.println("Counter there (2) : " + $Counter.count);
end 

rule "Counter shower 3" 
when 
    Counter()  
then 
System.out.println("Counters there (3) : ");
end 

rule "Counter creator" 
    when $Counter  : Counter(count == 2) 
then 
    insert (new Counter(3)); // STEP 3
     System.out.println("new Counter created ");
end

rule "Counter remover" 
    when 
    $Counter  : Counter(count == 1)
    exists Counter (count == 3) 
then 
    retract ($Counter) ; // STEP 4
     System.out.println("retract counter with ID = 1");
end

这是 kModule

<?xml version="1.0" encoding="UTF-8" ?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="rules" packages="rules">
        <ksession name="test" />
 </kbase>
</kmodule>

运行结果

Counter there (1) : 1
Counter there (2) : 1
Counters there (3) : 
Counter there (1) : 2
Counter there (2) : 1
Counter there (2) : 2
Counters there (3) : 
new Counter created 
Counter there (1) : 3
Counter there (2) : 1
Counter there (2) : 2
Counter there (2) : 3
Counters there (3) : 
retract counter with ID = 1
Counter there (2) : 2
Counter there (2) : 3

我的问题是:

  1. 程序代码不包含任何“kSession.delete”,所有事实都保存在工作内存中。因此,在我看来,规则“Counter Shower 1”..“Counter Shower 3”应该在每次 fireAllRules 调用后为工作内存中的每个 Counter 对象触发。 STEP 1 一次,STEP2 两次,STEP3 三次但输出列表指出只有“柜台淋浴 2”以这种方式工作。 “柜台淋浴 1”和“柜台淋浴 3”仅通过一次 fireAllRules 调用触发一次。

  2. 为什么规则“柜台淋浴 1”仅捕获最后插入的事实?其中是否存在隐藏行为?

3.为什么在收回计数== 1的对象计数器后仅“Counter Shower 2”触发?其他规则呢?

感谢您的帮助。

最佳答案

问题 1:程序代码不包含任何“kSession.delete”,所有事实都保存在工作内存中。因此,在我看来,规则“Counter Shower 1”..“Counter Shower 3”应该在每次 fireAllRules 调用后为工作内存中的每个 Counter 对象触发。 STEP 1 一次,STEP2 两次,STEP3 三次但输出列表指出只有“柜台淋浴 2”以这种方式工作。 “柜台淋浴 1”和“柜台淋浴 3”仅由一次 fireAllRules 调用触发一次。

您应该了解 fireAllRules 实际上并不会触发您知识库中的所有规则。这个名字有点误导。 :)

与其谈论规则“触发”,不如将其称为“激活”。您有一个有状态 session ,因此当您第一次调用 fireAllRules 时,您的三个规则将根据您最初插入的 Counter 激活。当您再次调用 insert/fireAllRules 时,这些规则仍会针对初始 Counter 激活!他们不需要再次激活。除非工作内存的状态发生变化导致规则停用和重新激活,否则您将看不到右侧发生任何事情。

这实际上是有状态 session 的全部要点。您的知识库可以逐步“学习”事实,并可以根据现有知识评估新事实。

无状态 session 的目的是从零知识的假设中评估每个事实。

问题 2:为什么规则“柜台淋浴 1”仅捕获最后插入的事实?

您有一个有状态 session ,因此在第一个 fireAllRules 上激活 Counter 初始插入的匹配。从那时起,工作内存中没有发生任何影响初始激活的变化,因此当您再次 fireAllRules 时,它不再需要激活。

问题 3:为什么在收回对象 Counter 且 count == 1 后,仅“Counter Shower 2”触发?其他规则呢?

“Counter Shower 2”规则是唯一受撤回影响的规则,因为它有一个累加器对您的 Counter 事实进行计数。

关于java - Drools 中的工作内存和对象插入行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26420666/

相关文章:

java - 从多个线程填充 map

java - 仅可点击 ListView android 中 5 个 TextView 中的 4 个 TextView

java - 使用 Drools 的动态规则

java - 来自 Java API 的 Drools 规则语言

language-agnostic - 如何在语言之间共享配置信息或业务规则

java - JTree不断扩展的问题

java - 需要帮助配置 maven .pom 来构建 .exe 文件

java - 在 jbpmm 中将变量设置为脚本任务流程

java - Drools 决策表对象比较给出了相反的结果

dynamic - 开发人员如何让业务用户定义应用逻辑?