2014-04-21 43 views
1

我有以下Drools規則文件,我向其發送的地圖填充了自定義對象(NodeElement),map是一個全局變量,因爲它必須被所有規則訪問,並且有另一個全局變量錯誤,當規則失敗時填充。我已經使用了eval並能夠成功執行它。經過一番研究,發現eval有一些性能問題?如何訪問drools中的自定義對象的地圖

我的問題是...

1)性能問題可以忽略不計?

2)是使用eval一個很好的做法? 3)如果我不得不重寫這些規則嗎?這是做到這一點的最佳方式?

import java.util.Map; 
import com.infodev.pojo.NodeElement; 
import com.main.Errors; 
import com.validation.DateValidation; 

global java.util.Map map; 
global com.main.Errors errors; 


rule "Fixed/Floating ccy rule" 

    when 
     eval(!((NodeElement)map.get("FixedCurrency")).getValue().equals(((NodeElement)map.get("FloatingCurrency")).getValue())) 
    then 
     errors.addError("Currency", "Fixed currency should be same as Floating currency"); 
end 

rule "Payment/Settlement date rule" 

    when 
     eval(!(DateValidation.paymentDateValidation(((NodeElement)map.get("tradeDate")).getValue(),((NodeElement)map.get("paymentDate")).getValue()))) 

    then 
     errors.addError(map.get("paymentDate").toString(), "Payment date should be after trade date"); 

end 

和地圖是:

Map<String, NodeElement> map = new HashMap<String, NodeElement>(); 
    map.put("FixedCurrency", new NodeElement("FixedCurrency", "USD")); 
    map.put("FloatingCurrency", new NodeElement("FloatingCurrency", "UD")); 
    map.put("tradeDate", new NodeElement("tradeDate", "2012-01-22")); 
    map.put("paymentDate",new NodeElement("paymentDate", "2012-01-2")); 

回答

1

鑑於NodeElement可以使用您用作Map的關鍵字的相同String來標識,爲什麼不直接將NodeElement插入到會話中?通過這樣做,你可以重寫你的規則是這樣的:

rule "Fixed/Floating ccy rule" 
when 
    $n1: NodeElement(id == "FixedCurrency") 
    $n2: NodeElement(id == "FloatingCurrency", value != $n1.value) 
then 
    errors.addError("Currency", "Fixed currency should be same as Floating currency"); 
end 

rule "Payment/Settlement date rule" 
when 
    $n1: NodeElement(id == "tradeDate") 
    $n2: NodeElement(id == "paymentDate", value != $n1.value) 
    eval(!(DateValidation.paymentDateValidation($n1.value, $n2.value))) 
then 
    errors.addError($n2.value.toString(), "Payment date should be after trade date"); 
end 

我不能告訴你,如果通過重新編寫規則,這樣會增加你的表現與否。這也取決於其他事情。我認爲,通過這種新方法獲得的一件事就是可讀性。

希望它有幫助,

+1

爲什麼不去完整的方式,並使用'FixedCurrency','TradeDate'等作爲類型名稱。這將*真正*使它可讀;-) – laune

+0

感謝它works.But只是問是否有更好的方法來做到這一點?它可以更有效地實現嗎? –

-1

你不必規則,你有if語句(僞裝成規則)處理值在Map對象和其他靜態對象。 (爲什麼不添加地圖後運行這些檢查?)

沒有eval我可以在你的規則中看到。

如果你需要eval,你必須使用eval,如果你能避免它,避免它。

+0

對不起,這些如果實際上是eval。並且不確定當你在添加映射後說檢查時你所暗示的意思是否意味着使用if else而不是drools本身?......上述規則可能很簡單n可以使用if-else來解決,但是我的實際規則將會很複雜。你能指出我在正確的方向如何做到這一點,而無需使用eval? –

+0

你在這些「規則」中沒有訪問工作記憶中的任何事實,所以你在那裏編寫的只是一個if語句。是的,您可以在這些'map.put(...)'語句之後將這些檢查作爲Java代碼運行Java代碼。 - 現在他們寫了,你必須使用'eval'。如果它們更復雜,那麼如果發表規則的僞裝,它們就會變得更加複雜。如果他們都是這樣的,只是訪問一些靜態對象,那麼你就錯過了生產規則系統的全部要點,並且可以堅持使用Java。 – laune

+0

此處顯示的地圖是一個靜態內容,但實際上生成的地圖將是xml文檔中的鍵和值對的集合,其中鍵是xml標記,值是該標記的值。想要在此映射上運行一些業務規則來檢查xml文檔是否是有效的文檔?這是我的用例。並且當你說事實時,意思是傳遞給drools的工作內存中的java對象是正確的?如果是這樣,那麼我們不能使用地圖對象而不是Java類對象?並且它的確如此陳述的大部分規則將是複雜的,但我認爲流口水可以以某種方式提供幫助。 –

相關問題