java - 如何在 DRL 文件中传递规则条件的参数值?
问题描述
我是 Drools 的新手。我想在 rule.drl 文件中传递规则条件的参数。
目前我有这样的代码: -
rule "PREPAID TOP UP LIMIT" salience 1
when
cardObject : Card(cardType=="prepaid" && loadCash > 25000);
then
cardObject.setTransactionResposne(false);
cardObject.setMessage("Top up limit exceeds ");
end;
正如您在此代码中看到的,cardType 和 loadCash 分别与“预付”和 25000 与静态值进行比较。但我想从 java 类中启动这个静态值。
那么,我该如何传递这个参数。请分享一些解决方案。
解决方案
你基本上有两个选择:
- 将条件传递到工作记忆中。
- 将条件声明为全局变量。
全局变量通常不被接受,但为了完整起见,我将包括它。
对于第一个选项,将条件传递到工作内存中,我建议创建一个简单的对象,其中声明了这些条件以及适当的 getter/setter。
例如:
public class CardLimits {
private String type;
private Integer limit;
// getters and setters here
}
您可以将CardLimits
实例(或多个实例,如果您有多种类型)与您的Card
实例一起传递到工作内存中。那么你的规则可能如下:
rule "PREPAID TOP UP LIMIT"
salience 1
when
CardLimits( $max: limit != null, $type: type == "prepaid" )
cardObject : Card( cardType == $type && loadCash > $max);
then
cardObject.setTransactionResposne(false);
cardObject.setMessage("Top up limit exceeds ");
end
(轻微的挑剔:你后面的分号end
不应该在那里。而且你在右手边拼错了“响应”。)
CardLimits 实例将与您的 Card 实例一起传递到规则中,如下所示:
KieSession kieSession = ...;
Card card = ...; // the Card you are passing into the rules
CardLimits limits = ...; // the limits
kieSession.insert( card );
kieSession.insert( limits );
kieSession.fireAllRules();
请注意,对于此结构,您可以为多种限制类型设置一个规则。
因此,例如,假设您有两种类型的卡“预付”和“礼品”,用不同的 CardLimits 实例描述它们的限制。然后,您可以使用一条规则来处理这两种情况:
rule "ANY TOP UP LIMIT"
salience 1
when
CardLimits( $max: limit != null, $type: type ) // no restriction on 'type'
cardObject : Card( cardType == $type && loadCash > $max);
then
cardObject.setTransactionResposne(false);
cardObject.setMessage("Top up limit exceeds ");
end
我还建议使用枚举而不是字符串作为卡片类型。
通过传入一个对象,您将来还可以自由添加其他条件。例如,假设您想在卡在特定天数内过期时拒绝充值——您可以根据需要将其添加到您的条件对象中。
为了完整起见,您的替代方法是使用全局变量。这通常是您要避免的事情,出于同样的原因,我们试图在大多数语言中避免使用全局变量,除非没有其他选择。当我第一次开始做 Drools(回到 Drools 5)时,这是一种非常普遍的做法,但此后普遍失宠。
global Integer max;
global String type;
rule "PREPAID TOP UP LIMIT"
salience 1
when
cardObject : Card( cardType == type && loadCash > max);
then
cardObject.setTransactionResposne(false);
cardObject.setMessage("Top up limit exceeds ");
end
这会将您限制为所有规则的单一类型和最大值。所以你不能同时处理多张卡片。
调用规则时设置全局变量:
KieSession kieSession = ...;
Card card = ...; // the Card you are passing into the rules
// set the globals
kieSession.setGlobal( "max", (Integer)25000 );
kieSession.setGlobal( "type", "prepaid" );
kieSession.insert( card );
kieSession.fireAllRules();
我不建议为此使用 Globals。我只包括这种可能性,因为这是您可以做的事情。
推荐阅读
- testing - 在夹具挂钩中使用用户代理进行浏览器检测
- python - pandas中连续变量的动态分箱
- java - 如何自定义显示 JUnit 测试结果的方式?
- hadoop - Apache Flume 能否从 AWS Kinesis 或 GCP Pub/Sub 收集数据?
- javascript - useState 和 useEffect 有什么区别?
- ruby - 续集:如何将变量传递给选择块?
- java - 在java程序中得到意外的输出
- mysql - 如何选择临时表并立即更新
- robotframework - 如何在 Robot Framework 中创建自定义测试用例设置,如标签
- java - Spring Security 和 GraphQL