重用部分 Drools `when` 语句

Reuse part of Drools `when` statement

我有大量具有相似 when 部分的 Drools 规则。例如

rule "Rule 1"
    when
        trn: TransactionEvent()

        // some `trn` related statements

        not ConfirmEvent (
            processMessageId == trn.groupId )
    then
        // some actions
end

rule "Rule 2"
    when
        trn: TransactionEvent()

        // some other `trn` related statements

        not ConfirmEvent (
            processMessageId == trn.groupId )
    then
        // some other actions
end

是否可以定义一次这个语句

not ConfirmEvent (
    processMessageId == trn.groupId )

并在需要的地方以某种方式重复使用?

显然 not CE 本身无效,因为它引用了一些 trn。但是由于 trn 是由另一个 CE 引入的,您可以根据它们的组合使用扩展:

rule "Commont TE + not CE"
when
    trn: TransactionEvent()
    not ConfirmEvent ( processMessageId == trn.groupId )
then
end

rule "Rule 1" extends "Commont TE + not CE"
when
    // some `trn` related statements
then
    //...
end

等等,对于 Rule 2 和其他人。

两种方法思路:

  1. 在每个规则中使用规则“extends”关键字来扩展包含共享 when 语句的基本规则。

  2. 使用推断事实的共享 when 语句创建规则(“提取规则”)。在需要共享条件的规则的 when 条件中使用该事实。此选项通常是我的首选方法,因为它为这些条件定义了一个“概念”(命名事实),并且仅针对每个规则评估一次。

    #2 的规则示例:

    rule "Transaction situation exists"
        when
            trn: TransactionEvent()
    
            // some `trn` related statements
    
            $optionalData : // bind as wanted
    
            not ConfirmEvent (
                processMessageId == trn.groupId )
        then
            InferredFact $inferredFact = new InferredFact($optionalData);
            insertLogical($inferredFact);
    end
    
    rule "Rule 1"
        when
            InferredFact()
            AdditionalCondition()
        then
            // some actions
    end
    
    rule "Rule 2"
        when
            InferredFact()
            OtherCondition()
        then
            // some other actions
    end