【问题标题】:Issue with accessors in DroolsDrools 中的访问器问题
【发布时间】:2016-07-04 16:26:53
【问题描述】:

我在 Drools 中更新组合对象时遇到了一个特殊场景:

declare A
    @propertyReactive
    flag: Boolean
end

declare B
    flag: Boolean
end

declare C
    @propertyReactive
    attrA: A
    attrB: B
end

rule "Create A"
    when
        not A()
    then
        insert(new A());
        System.out.println("OBJECT A CREATED");
end

rule "Create B"
    when
        not B()
    then
        insert(new B());
        System.out.println("OBJECT B CREATED");
end

rule "Create C"
    when
        $A:A()
        $B:B()
        not C()
    then
        insert(new C($A,$B));
        System.out.println("OBJECT C CREATED");
end

rule "Modify A"
    when
        $A:A(flag == false)
        C()
    then
        modify($A) {setFlag(true)};
        String $output = "Now A is " + $A.getFlag();
        System.out.println($output);
end

rule "Print C when C is False"
    when
        C($A:attrA, attrA.flag == false, $B:attrB)
    then
        String $output = "A is " + $A.getFlag() + " and B is " + $B.getFlag();
        System.out.println($output);
end 

rule "Print C when C is True"
    when
        C($A:attrA, attrA.flag == true, $B:attrB)
    then
        String $output = "A is " + $A.getFlag() + " and B is " + $B.getFlag();
        System.out.println($output);
end

rule "Print C when C is True 2"
    when
        C($A:attrA, $B:attrB)
        A(this == $A, flag == true)
    then
        String $output = "2 A is " + $A.getFlag() + " and B is " + $B.getFlag();
        System.out.println($output);
end

输出是:

OBJECT A CREATED
OBJECT B CREATED
OBJECT C CREATED
A is false and B is false
Now A is true
2 A is true and B is false

所以我有以下问题:

  • 为什么规则“当 C 为真时打印 C”没有触发?
  • 为什么我需要将该规则重写为“Print C when C is True 2”以使其工作?
  • 有人对此有解释吗?

Drools 在使用嵌套类的访问器时似乎存在问题...

非常感谢。

【问题讨论】:

    标签: class nested drools composite accessor


    【解决方案1】:

    Drools 仅对对模式中使用的对象执行的更改做出反应,而不对它们可能包含的任何嵌套对象引用做出反应。这也不完全正确。

    当您在 Drools 中修改事实(或其任何嵌套对象引用)时,您可以选择是否让 Drools 知道此修改。在您的情况下,您永远不会通知 Drools 有关它们的信息。这就是为什么您的规则取决于(非确定性)评估顺序的原因。

    如果您想让 Drools “知道”某个事实的修改,那么您必须在发生这些修改的规则的 RHS 中使用 modifyupdate 函数。

    在您的特定情况下,您不仅有嵌套对象,还有嵌套事实:AC。即使A 是事实,A 上的更改(即使已正确通知 Drools)也永远不会触发重新评估这样的模式:

    C(attrA.flag == true)
    

    原因是因为模式的类型是C而不是A。在这种情况下,像 Print C when C is True 2 规则这样编写的规则是更好的方法。

    希望对你有帮助,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多