是否可以为drools规则添加自定义属性?

时间:2011-04-08 12:54:35

标签: java jboss drools

我们将为客户使用Drools实施规则引擎,其中一个要求是能够说规则与特定的法律要求相关联。

例如,法律规定驾驶执照只能发给18岁或以上的人,所以我们有:

rule "Driving Licence: Age >= 18"
    when
        $applicant: Applicant(age < 18)
        $application: Application()
    then 
        $application.setValid(false);
end

或计算税额

rule "Tax: Top bracket"
    when
        $return: Return(income > 44000)
    then 
        $application.setTopBracket(true);
end

或类似。

一种解决方案是在名称中包含法律要求:

rule "Driving Licence: Age >= 18: Section 103 RTA 1988"

问题:实现这一目标的最佳方法是什么?名字是唯一的方式吗?有没有办法为规则添加自定义属性?如果是这样,它是强制性的吗?我也可以使用评论,但我宁愿避免这样做。

如果在规则跟踪中我们也可以看到这些属性的痕迹,那将是很好的,但这并不重要。

请注意,我不想更改规则逻辑,我只想说“这条规则来自这条法则”。该规则的决定并不重要。我不想更改setValid setter。

3 个答案:

答案 0 :(得分:8)

您可以使用规则元数据。元数据不会影响您的规则,除非您愿意,您可以在LHS或RHS中使用它。您还可以在调试时访问元数据,例如,您可以使用AgendaFilter打印元数据,并查看正在触发的规则以及它们具有哪些法律要求。

如果您想强制每个规则的元数据,您需要自己编写检查代码。

@metadata_key( metadata_value1, metadata_value2, ...  )

rule "Driving Licence: Age >= 18"
@LegalRequirement("Section 103 RTA 1988")
when
    $applicant: Applicant(age < 18)
    $application: Application()
then 
    $application.setValid(false);
end

以下是AgendaFilter的示例。如果返回false,则会阻止规则触发。我只是用它来打印法律要求:

StatefulKnowledgeSession ksession= createKSession();   
ksession.fireAllRules(new AgendaFilter() {
  public boolean accept(Activation activation) {
    Map<String, Object> metaData = activation.getRule().getMetaData();
    if (metaData.containsKey("LegalRequirement")) {
      System.out.println(metaData.get("LegalRequirement"));
    }
    return true;
  }
});

或者如果你想在RHS中使用它:

rule.getMetaData().get("LegalRequirement");

如果您使用Guvnor管理规则,您还可以使用类别设置。对于存储在Guvnor中的每个资产,类别是强制性的。

答案 1 :(得分:1)

您可以修改方法Application.setValid(false)以获取其他参数,这将是法律要求。这样你就可以把它呈现给你的顾客。

答案 2 :(得分:0)

我同意Guillaume Alvarez的观点,但请记住(可能在您的系统中)某个应用程序可能因为多种原因而被拒绝,因此您可能会采用以下方法:

application.addInvalidReason(SomeType)

这个方法可能会被同一个应用程序的几个规则调用......