2014-04-21 42 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类对象?并且它的确如此陈述的大部分规则将是复杂的,但我认为流口水可以以某种方式提供帮助。 –

相关问题