drools_07_macro_functions
delete()和retract() 宏函數
delete() 用于在rule RHS中將對象從工作內存中刪除, retract()函數有同樣的作用, 不過已經被標記為廢棄狀態.
insert() 宏函數
insert() 用于在rule RHS中增加新的fact對象, 新的fact對象會自動完成模式匹配, 所以需要避免循環觸發問題.
update()和 modify() 宏函數
update和modify 用于在rule RHS中修改fact對象,并期望對該fact對象重新模式匹配, 如果不期望重新模式匹配, 不需要調用這兩個宏函數, 調用這兩個函數需要額外注意不要引起循環rule觸發.
循環觸發問題
當然, drools 也有機制盡量避免無謂的重復模式匹配, 具體說明:
- 在update()/modify()所在的rule, 如果更新的屬性同時用在了LHS條件中, 那么drools認為需要觸發該規則, 這時很容易發生循環觸發問題, 需要格外注意, 可以為rule增加 no-loop 屬性來避免.
- 在update()/modify()所在的rule, 如果修改的屬性沒用在了LHS條件中, drools會智能地判斷出沒有必要觸發該規則, 對于該規則來講是沒有循環重復問題. 但如果先觸發了另一個規則, 在那個規則中又對原規則的LHS條件屬性做了修改, 這樣還會出現循環觸發問題, 這時即使加了no-loop 屬性也不管用.
// 修改了amount屬性, 但是LHS用的是originalPrice屬性, 所以對于本規則不會循環觸發
rule "not_worry_loop"
when
$order:Order(originalPrice>0)
then
$order.setAmount(100);
update($order) ;
System.out.println("rule fired") ;
end
// 修改了amount屬性, LHS也使用了amount屬性, 所以會循環觸發
rule "always_loop"
when
$order:Order(amount>0)
then
$order.setAmount(100);
update($order) ;
System.out.println("rule fired") ;
end
update() 和 modify()區別
- 推薦使用 modify() 而不是 update()
官方的解釋是: After a fact has changed, you must callupdatebefore changing another fact that might be affected by the updated values. To avoid this added step, use themodifymethod instead. - 語法比較
update()語法簡單, modify()語法比較奇怪, 要將修改的屬性包在{ } 中, 見下面的示例.
rule "not_worry_loop2"
when
$order:Order(originalPrice>0)
then
modify($order) {
setAmount(100);
}
System.out.println("rule fired") ;
end

浙公網安備 33010602011771號