人們常常混淆方法和規則,而新接觸規則的用戶經常會問:“我如何稱呼規則?” 在最後一節之後,你現在感覺自己像一個規則專家,答案很明顯,但我們總結一下這些差異。
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