我们将为客户使用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。
答案 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)
这个方法可能会被同一个应用程序的几个规则调用......