2017-07-25 68 views
0

我們對結構如下規則工作:修改/更新元素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 

這將如何影響整個過程?工作記憶的實現將激發第一個重新評估的規則。這條規則已經發布了兩次,因爲我們遇到了兩個未經驗證的元素。剩餘的元素是否僅被評估一次或多次?

回答

0

您的第一個問題的答案是兩個片段之間沒有區別。(在第二個問題的兩個之間插入的陳述會影響我的答案。)

第二個問題的方案不使用同一表單中的更新。插入列表作爲事實,但是對列表元素進行操作通常被認爲是不好的。插入列表元素。容器可能會或可能不會用作容納列表元素到一個事務或任何其他事物的容器。

+0

非常感謝您的回答:關於澄清的第一個問題,以及關於指出不良做法的第二個問題。我遵循您的準則重新編寫了規則,現在它完美地工作。在我的情況下,容器仍然有用,但它已經超出了工作記憶,節省了很多潛在的問題。是否有任何文檔或鏈接可用於在使用Drools進行編碼時提供不良實踐信息? – Ruurd