我們對結構如下規則工作:修改/更新元素Drools的
- 我們有一個包含驗證和未經驗證的元素的列表。驗證和未驗證之間的區別是通過給元素賦予不同的狀態來完成的。
- 我們從列表中獲取未驗證的元素。
- 將每個未驗證的元素與同一列表中的驗證元素進行比較。
- 比較之後,未驗證元素將成爲驗證未驗證元素時需要考慮的驗證元素。
當我們想要更新元素的原始ArrayList時出現問題。我們需要能夠更新工作內存中剛剛在其原始ArrayList中驗證的未驗證元素,以便循環可以考慮「刷新」ArrayList。
三個問題:
首先,就是使用修改和更新的Drools之間準確的區別。據Drools的文件:
「在一個規則的右邊推薦的modifystatement, 因爲它使的變化,並通知在一個 聲明的引擎。」
所以一個和其他的區別將只是簡單的語義,如:
modify($sprinkler) { setOn(true) };
和
$sprinkler.setOn(true);
update($sprinkler);
這是假設是正確的?
其次,是否可以更新或修改Drools工作內存中ArrayList中的特定元素,而無需使用普通Java迭代器(「for」)。在我們的例子中,每個元素都使用我們從列表中獲得的唯一ID進行標識,因此我們將有一個更新其狀態的有效參考(已驗證或未驗證)。
最後,我們知道更新工作內存會導致規則再次觸發。假設我們有一個包含兩個未驗證項目的ArrayList。如果我們要獲得所有未驗證的項目來驗證他們,我將創建一個規則,「第一」將觸發兩次,每個非驗證項目一次:
rule "first"
when
$listOfElements : java.util.ArrayList ()
$itemsToValidate : Element (status == "not validated") from $listOfElements
then
//do something or not
end
如果在第二條規則我會驗證某些項目,並希望將未驗證元素的狀態更改爲這樣的工作記憶驗證:
rule "second" extends "first"
when
//we validate attributes of the non-validated element against attributes of the validated elements
then
//my second question is if something like this is actually possible (solution without Java iterator)
$itemsToValidate.setStatus("validated")
modify ($listOfElements) { $itemsToValidate };
end
這將如何影響整個過程?工作記憶的實現將激發第一個重新評估的規則。這條規則已經發布了兩次,因爲我們遇到了兩個未經驗證的元素。剩餘的元素是否僅被評估一次或多次?
非常感謝您的回答:關於澄清的第一個問題,以及關於指出不良做法的第二個問題。我遵循您的準則重新編寫了規則,現在它完美地工作。在我的情況下,容器仍然有用,但它已經超出了工作記憶,節省了很多潛在的問題。是否有任何文檔或鏈接可用於在使用Drools進行編碼時提供不良實踐信息? – Ruurd