Повторное использование части инструкции Drools `when`

#java #drools

#java #пускает слюни

Вопрос:

У меня есть множество правил Drools с аналогичными when частями. Например.

 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 )
  

и повторное использование как-то там, где это необходимо?

Ответ №1:

Две идеи подхода:

  1. Используйте ключевое слово rule «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
      

Комментарии:

1. Не могли бы вы, пожалуйста, объяснить вторую идею и проиллюстрировать ее с помощью некоторого кода (правил)?

2. Добавлено к моему ответу.

Ответ №2:

Должно быть очевидно, что not CE недействителен сам по себе, поскольку он ссылается на some 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 и других.