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.java。https://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.java。https://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 的任何条件不匹配,但没有通过 中断 激活,则该规则无法编译,因为不会到达规则的条件部分。