规则与方法以及叉积
规则和方法的比较
方法特点
- 方法被直接调用。
- 传递了特定实例。
- 一个调用导致一次执行。
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, Sprinkler,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