首页 文章

需要设计指南来实施Drools规则

提问于
浏览
0

我在我的应用程序中使用Drools 6.1.0 .

我们计划编写一个包含所有规则的巨大.drl文件 .

主要有两类规则1.空检查2.业务验证

使用ruleflow-group,activation-group和salience我计划在将事实添加到会话时管理要执行/触发的规则 .

即使采用这种方法,解决方案也不适合我,因为 .

可以说我有.drl文件

rule "rule1"
ruleflow-group "primary"
activation-group "NullCheck"
salience 5
when 
    $m : Message(innerMsg.something == null)
then 
    // do something

rule "rule2"
ruleflow-group "primary"
activation-group "NullCheck"
salience 4
when 
    $m : Message(innerMsg.something.something == null)
then 
    // do something

rule "rule3"
ruleflow-group "primary"
activation-group "NullCheck"
salience 3
when 
    $m : Message(innerMsg.something.something.something == null)
then 
    // do something

Drools文档说这个"All constraints are evaluated when a fact is inserted. From the Drools manual: The condition evaluation is not tied to a specific evaluation sequence or point in time, but that it happens continually, at any time during the life time of the engine."

所以发生的事情是执行此文件的代码在rule2上抛出Nullpointer Exception,因为 innerMsg.something.something 为NULL

Note: I do not want to club all the null checks using || in a single when statement because I want to capture specific null condition and based on that create the error message.

我的问题如下 .

  • 使用drools规则对链接对象执行Nullchecks是一个好主意 .

  • 我是否应该使用其他类似顺序规则执行的东西(不确定Drools中是否可用),这将允许我按特定顺序执行规则 .

  • 还有另一种方法可以实现这一目标

2 回答

  • 0

    您无法避免的是使用您的代码为空安全 .

    要么为访问具有子类型Object的字段的每个条件添加前缀,并使用空测试:

    Fact( field != null && field.subfield == whatsoever )
    

    或者您使用null-safe解除引用运算符:

    Fact( field!.subfield == whatsoever )
    

    请注意 ==!= 隐式为空安全,因此您可以编写

    Fact( field == whatever )
    

    如果 field == null 没有问题 .

    放弃使用激活组和显着性的想法尽可能快地实现流量控制 . 这将导致一个非常糟糕的规则设计,不可维护的代码和一般的不快乐 . 如果你不能,用Java或其他语言写出来 .

  • 0

    我认为http://drools-moved.46999.n3.nabble.com/rules-users-Drools-Activation-Group-td3546598.html可能与您所看到的相关 . 您可以尝试以下内容 .

    rule "rule2" ruleflow-group "primary" activation-group "NullCheck" salience 4 when $m : Message(innerMsg != null) Message(this == $m, innerMsg.something != null) Message(this == $m, innerMsg.something.something == null) then

    这违背了你避免一堆||的愿望在某种程度上,但它是一种不同的语法 .

相关问题