Drools学习笔记(三)---方法与规则
程序员文章站
2022-05-07 21:54:10
...
人们常常混淆方法和规则,而新接触规则的用户经常会问:“我如何称呼规则?” 在最后一节之后,你现在感觉自己像一个规则专家,答案很明显,但我们总结一下这些差异。
public void helloWorld(Person person) {
if ( person.getName().equals( "Chuck" ) ) {
System.out.println( "Hello Chuck" );
}
}
方法直接调用。
通过特定实例。
一次调用导致单次执行。
rule "Hello World" when
Person( name == "Chuck" )
then
System.out.println( "Hello Chuck" );
end
只要将规则插入引擎,规则就可以通过匹配任何数据来执行。
永远不能直接调用规则。
无法将特定实例传递给规则。
根据匹配,规则可能会触发一次或多次,或者根本不会触发。
交叉产品
想象一下,火灾报警示例中的数据与以下规则结合使用,其中没有字段约束:
rule "Show Sprinklers" when
$room : Room()
$sprinkler : Sprinkler()
then
System.out.println( "room:" + $room.getName() +
" sprinkler:" + $sprinkler.getRoom().getName() );
end
在SQL术语中,这就像在做,select * from Room, Sprinkle
r并且Room表中的每一行都将与Sprinkler表中的每一行连接,从而产生以下输出:
room:office sprinkler:office
room:office sprinkler:kitchen
room:office sprinkler:livingroom
room:office sprinkler:bedroom
room:kitchen sprinkler:office
room:kitchen sprinkler:kitchen
room:kitchen sprinkler:livingroom
room:kitchen sprinkler:bedroom
room:livingroom sprinkler:office
room:livingroom sprinkler:kitchen
room:livingroom sprinkler:livingroom
room:livingroom sprinkler:bedroom
room:bedroom sprinkler:office
room:bedroom sprinkler:kitchen
room:bedroom sprinkler:livingroom
room:bedroom sprinkler:bedroom
这些交叉产品显然会变得庞大,并且很可能包含虚假数据。交叉产品的大小通常是新规则作者的性能问题的根源。由此可以看出,总是希望约束交叉乘积,这是用变量约束完成的。
rule
when
$room : Room()
$sprinkler : Sprinkler( room == $room )
then
System.out.println( "room:" + $room.getName() +
" sprinkler:" + $sprinkler.getRoom().getName() );
end
这导致只有四行数据,每个房间都有正确的洒水喷头。在SQL(实际上是HQL)中,相应的查询将是select * from Room, Sprinkler where Room == Sprinkler.room
。
room:office sprinkler:office
room:kitchen sprinkler:kitchen
room:livingroom sprinkler:livingroom
room:bedroom sprinkler:bedroom