首页 > 解决方案 > 如何在 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 类中启动这个静态值。

那么,我该如何传递这个参数。请分享一些解决方案。

标签: javaspring-bootdrools

解决方案


你基本上有两个选择:

  1. 将条件传递到工作记忆中。
  2. 将条件声明为全局变量。

全局变量通常不被接受,但为了完整起见,我将包括它。


对于第一个选项,将条件传递到工作内存中,我建议创建一个简单的对象,其中声明了这些条件以及适当的 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。我只包括这种可能性,因为这是您可以做的事情。


推荐阅读