在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
所以我有以下问题:
看起来Drools在使用嵌套类的访问器方面存在问题......
非常感谢。
答案 0 :(得分:0)
Drools仅对模式中使用的对象执行的更改做出反应,而不对它们可能包含的任何嵌套对象引用做出反应。这也不完全正确。
当您在Drools(或其任何嵌套对象引用)中修改事实时,您可以选择让Drools知道此修改。在你的情况下,你永远不会通知Drools他们。这就是为什么你的规则依赖于(非确定性)评估顺序的原因。
如果你想让Drools"知道"关于对事实的修改,那么您必须在发生这些修改的规则的RHS中使用modify
或update
函数。
在您的特定情况下,您不仅拥有嵌套对象,还拥有嵌套事实:A
和C
。即使A
是事实,A
上的更改(即使已正确通知Drools)也不会触发重新评估此类模式:
C(attrA.flag == true)
原因是因为模式的类型是C
而不是A
。在这种情况下,像Print C when C is True 2
规则一样编写的规则是更好的方法。
希望它有所帮助,