16.9. DRL(THEN)中的规则操作

规则的 then 部分(也称为规则的 右 Hand Side(RHS) )包含满足规则条件部分时要执行的操作。操作由一个或多个 方法 组成,它们根据规则条件和软件包中的可用数据对象执行结果。例如,如果银行需要有 21 多年的时间(带有规则条件 Applica nt(年龄 < 21 )和 loan applicant 在 21 年下, "Underage" 规则的操作将在 21 年下 被设置,因为应用程序被退还到下限。

规则操作的主要目的是在决策引擎的工作内存中插入、删除或修改数据。有效的规则操作是 small、声明和可读。如果您需要在规则操作中使用需要或有条件的代码,请将该规则分成多个较小的子声明规则。

loan Application age 限制的规则示例

rule "Underage"
  when
    application : LoanApplication()
    Applicant( age < 21 )
  then
    application.setApproved( false );
    application.setExplanation( "Underage" );
end

16.9.1. DRL 中支持的规则操作方法

DRL 支持在 DRL 规则操作中使用的以下规则操作方法。您可以使用这些方法修改决策引擎的工作内存,而无需首先引用正常工作的内存实例。这些方法充当红帽决策管理器分发中 RuleContext 类提供的方法的快捷方式。

对于所有规则操作方法,请从红帽客户门户网站下载 Red Hat Process Automation Manager 7.13.2 Source Distribution ZIP 文件,再导航到 ~/rhpam-7.13.2-sources/src/kie-api-parent-$VERSION/kie-api/src/main/java/org/kie/api/runtime/rule/RuleContext.javahttps://access.redhat.com/jbossnetwork/restricted/listSoftware.html

set

使用此选项设置字段的值。

set<field> ( <value> )

设置 loan application 批准的值的规则操作示例

$application.setApproved ( false );
$application.setExplanation( "has been bankrupt" );

修改

使用此选项指定要修改的字段,并通知更改的决策引擎。此方法提供了一种结构化方法来事实更新。它将 更新操作与 设置者调用合并,以更改对象字段。

modify ( <fact-expression> ) {
    <expression>,
    <expression>,
    ...
}

修改 loan Application 数量和批准的规则操作示例

modify( LoanApplication ) {
        setAmount( 100 ),
        setApproved ( true )
}

update

使用此选项指定字段和要更新的完整相关事实,并通知更改的决策引擎。事实更改后,您必须在更改可能受更新的值影响的其他事实之前调用 更新。要避免添加的步骤,请改为使用 修改 方法。

update ( <object, <handle> )  // Informs the decision engine that an object has changed

update ( <object> )  // Causes `KieSession` to search for a fact handle of the object

更新 loan Application 数量和批准的规则操作示例

LoanApplication.setAmount( 100 );
update( LoanApplication );

注意

如果您提供属性更改监听程序,则在对象更改时不需要调用这个方法。有关 property-change 侦听器的更多信息,请参阅 Red Hat Decision Manager 中的 决策引擎

insert

使用它来将 新事实 插入到决策引擎的工作内存中,并根据需要定义结果字段和值。

insert( new <object> );

插入新 loan applicant 对象的规则操作示例

insert( new Applicant() );

insertLogical

使用它来在决策引擎中以逻辑方式插入新的事实。决策引擎负责对插入和检索事实的逻辑决策。在常规或声明插入后,必须明确调整事实。逻辑插入后,当插入事实的条件不再为 true 时,插入的事实会自动清空。

insertLogical( new <object> );

用于逻辑地插入新 loan applicant 对象的规则操作示例

insertLogical( new Applicant() );

delete

使用它来从决策引擎中删除对象。DRL 中还支持关键字 retract,并执行同样的操作,但 删除 通常优先于 DRL 代码,以便通过关键字 插入

delete( <object> );

删除 loan applicant 对象的规则操作示例

delete( Applicant );

16.9.2. 来自 drools 变量的其他规则操作方法

除了标准规则操作方法外,决策引擎还支持方法以及您可能在规则操作中使用的预定义 drools 变量。

您可以使用 drools 变量从 Red Hat Decision Manager 发行版中的 org.kie.api.runtime.rule.RuleContext 类调用方法,这也是标准规则操作方法所基于的类。对于所有 drools 规则操作选项,请从红帽客户门户网站下载 Red Hat Process Automation Manager 7.13.2 Source Distribution ZIP 文件,并进入 ~/rhpam-7.13.2-sources/src/kie-api-parent-$VERSION/kie-api/src/main/java/org/kie/api/runtime/rule/RuleContext.javahttps://access.redhat.com/jbossnetwork/restricted/listSoftware.html

drools 变量包含提供有关触发规则以及激活触发规则的事实集合的方法:

  • Drools.getRule().getName() :返回当前触发的规则的名称。
  • Drools.getMatch() :返回激活当前触发规则的 匹配。它包含用于记录和调试目的的信息,用于实例 drools.getMatch().getObjects() 返回对象列表,启用以正确的元顺序触发的规则。

drools 变量中,您还可以获得对 KieRuntime 的引用,提供与正在运行的会话交互的实用方法,例如:

  • Drools.getKieRuntime().halt() :如果之前名为 fireUntilHalt() 的用户或应用程序,则终止规则执行。当用户或应用程序调用 fireUntilHalt() 方法时,决策引擎以 主动模式 启动并评估规则,直到用户或应用程序明确调用 halt() 方法。否则,决定引擎以 被动模式 运行,并仅在用户或应用程序明确调用 fireAllRules() 方法时评估规则。
  • Drools.getKieRuntime().getAgenda() :返回对 KIE 会话 Agenda 的引用,并依次提供对规则激活组、规则条件组和 ruleflow 组的访问权限。

访问日程表组"CleanUp"的示例,并设置重点

drools.getKieRuntime().getAgenda().getAgendaGroup( "CleanUp" ).setFocus();

+ 本示例将重点设置为规则所属指定索引组。

  • pacemaker.getKieRuntime().setGlobal(), ~.getGlobal(): ~.getGlobals(): Sets 或 retrieve global variables.
  • Drools.getKieRuntime().get Environment (): 返回运行时环境,类似于您的操作系统环境。
  • Drools.getKieRuntime().getQueryResults(<string> query): 运行查询并返回结果。

16.9.3. 具有条件和命名后果的高级规则操作

通常,有效的规则操作是小的、声明性且可读。然而,在有些情况下,每个规则具有单一后果的限制可能有一定难度,从而导致详细和重复的规则语法,如下例所示:

具有详细和重复语法的规则示例

rule "Give 10% discount to customers older than 60"
  when
    $customer : Customer( age > 60 )
  then
    modify($customer) { setDiscount( 0.1 ) };
end

rule "Give free parking to customers older than 60"
  when
    $customer : Customer( age > 60 )
    $car : Car( owner == $customer )
  then
    modify($car) { setFreeParking( true ) };
end

重复部分解决方案是使第二规则扩展第一条规则,如以下修改的示例所示:

有扩展条件的部分增强示例规则

rule "Give 10% discount to customers older than 60"
  when
    $customer : Customer( age > 60 )
  then
    modify($customer) { setDiscount( 0.1 ) };
end

rule "Give free parking to customers older than 60"
    extends "Give 10% discount to customers older than 60"
  when
    $car : Car( owner == $customer )
  then
    modify($car) { setFreeParking( true ) };
end

作为更有效的替代方法,您可以使用修改后的条件和标记的相应规则操作将这两个规则整合到一条规则中,如下例所示:

带有条件和名为 results 的整合示例规则

rule "Give 10% discount and free parking to customers older than 60"
  when
    $customer : Customer( age > 60 )
    do[giveDiscount]
    $car : Car( owner == $customer )
  then
    modify($car) { setFreeParking( true ) };
  then[giveDiscount]
    modify($customer) { setDiscount( 0.1 ) };
end

这个示例规则使用两个操作:通常的默认操作以及名为 giveDiscount 的另一个操作。当一个超过 60 年的客户在 KIE 基础中发现时,giveDiscount 操作是激活的,无论客户是否拥有回车。

您可以使用额外条件(如以下示例中的 if 语句)配置命名结果的激活。if 语句中的条件始终评估在之前紧随它的模式。

带有额外条件的合并示例规则

rule "Give free parking to customers older than 60 and 10% discount to golden ones among them"
  when
    $customer : Customer( age > 60 )
    if ( type == "Golden" ) do[giveDiscount]
    $car : Car( owner == $customer )
  then
    modify($car) { setFreeParking( true ) };
  then[giveDiscount]
    modify($customer) { setDiscount( 0.1 ) };
end

您还可以使用嵌套(如果构建)等嵌套评估不同的规则条件,如以下更复杂的示例所示:

具有更复杂的条件合并的示例规则

rule "Give free parking and 10% discount to over 60 Golden customer and 5% to Silver ones"
  when
    $customer : Customer( age > 60 )
    if ( type == "Golden" ) do[giveDiscount10]
    else if ( type == "Silver" ) break[giveDiscount5]
    $car : Car( owner == $customer )
  then
    modify($car) { setFreeParking( true ) };
  then[giveDiscount10]
    modify($customer) { setDiscount( 0.1 ) };
  then[giveDiscount5]
    modify($customer) { setDiscount( 0.05 ) };
end

这个示例规则为 10% 的折扣,免费向高金客户打电话,但只购买 5% 的折扣,而无需免费向 Silver 客户打电话。该规则激活了名为 giveDiscount5 的后果,其关键字为 break 而不是 do。关键字在决策引擎日程表中产生后果,使规则条件的其余部分能够继续评估,同时 中断 会阻止任何进一步的状况评估。如果一个命名后果与具有 do 的任何条件不匹配,但没有通过 中断 激活,则该规则无法编译,因为不会到达规则的条件部分。