Одиночное наследование в слюнях - PullRequest
0 голосов
/ 07 апреля 2020

Мы используем версию drools 7.31. У нас есть одно большое правило, которое должно быть повторно использовано в других правилах. Базовая функциональность c, которая нам нужна, заключается в запуске правила SUPER, когда выполняются условия SUPER и SUB. Кажется, что в старой версии было ключевое слово "extends", с помощью которого это было возможно. Я смотрел на этот старый пост, который может достичь этого -

drools наследование правил

Когда я попробовал мой конец с версией 7.31, то и SUPER, и SUB правила увольняют самостоятельно. Вот пример того, чего я пытаюсь достичь:

rule "super"
    @description("Generic super rule")
    when 
        $person : Person()
        a : PersonInput() from $person.getInput()
        if (a.getPersonId() == 1) break[pvd1]
        else if (a.getPersonId() == 2) break[pvd2]
    then System.out.println("Default then = " + a.getPersonId());
    then[pvd1] System.out.println("Super RULE has person id = " + a.getPersonId());
    then[pvd2] System.out.println("Super RULE has person id = " + a.getPersonId());
end

rule "sub" extends "super"
    @description("Sub rule")
    when
        c : PersonInput(HouseholdId == "99999") from $person.getInput()
    then
        System.out.println("Sub RULE has HouseholdId == 99999 == " + c.getPersonId());
end

Результат, который я получаю, - это сначала все лица с персоналом 1/2 всех домохозяйств, затем второе правило - печать только 99999 идентификаторов домохозяйств.

Вывод, который я ожидаю, состоит в том, чтобы просто напечатать personId 1/2 ofTheidIID 99999.

Спасибо.

1 Ответ

1 голос
/ 09 апреля 2020

Drools 7.31 все еще поддерживает механизм 'extends'. Проблема здесь в том, что при расширении базового правила базовое правило срабатывает. (Это отчасти очевидно; если базовое правило недействительно для стрельбы, то дочернее правило недействительно для стрельбы. Если база является действительной для стрельбы , то она срабатывает. И когда запускается дочернее правило, также запускается родительское правило.)

Традиционный способ обойти это - использовать три правила. «Базовое» правило не должно иметь никаких последствий (то есть не должно быть правой части / затем предложения), поэтому оно просто перечисляет общие условия. Тогда последствия «супер» правила заключаются в правиле, которое расширяет базовые правила, не имеет никаких дополнительных условий «когда» и имеет предложение then как нормальное. И правило «sub» также расширяет «base», включает его дополнительные условия, а затем и свои собственные последствия. Если вы не хотите, чтобы «super» срабатывал, когда «sub» делает, вы делаете их взаимоисключающими.

Вот намеренно упрощенный пример:

rule "Base Rule"
when
  $person: Person( $input: input != null )
  PersonInput( $id: personId in (1, 2) )
then
// intentionally no 'then' clauses
end

rule "Super" extends "Base Rule"
when
  // No additional conditions, just use whatever is in Base Rule
then
  System.out.println("Person has id: " + $id);
end

rule "Sub" extends "Base Rule"
when
  PersonInput( householdId == "99999") from $input
then
  System.out.println("Household ID is 99999; id: " + $id);
end

Теперь, если мы этого не сделаем если «Super» срабатывает, когда «Sub» делает, мы просто делаем его взаимоисключающим из «Sub»:

rule "Super" extends "Base Rule"
when
  // This is the condition from Sub, inverted:
  PersonInput( householdId != "99999" ) from $input
then
  System.out.println("Person has id: " + $id);
end

По сути, когда вы расширяете правило, вы расширяете оба, когда и тогдашние пункты. Предложение (последствия) родительского правила then сработает раньше, чем последствия дочернего правила. Кроме того, если ребенок недействителен, но родитель есть, вы все равно уволите родителя. Таким образом, если у вас есть, скажем, 3 дочерних правила и родительское правило, родитель может быть запущен до 4 раз: один раз, когда он оценивается сам по себе, и затем еще 3 раза один раз для оценки дочернего элемента. Ситуация становится особенно странной, когда вы используете сеансы с состоянием и предложения update / insert.

Шаблон базового правила «без последствий», который я показал, развился из этой реальности. Следуя этой схеме, не имеет значения, сколько раз срабатывает «Базовое правило», потому что нет никаких побочных эффектов (последствия / затем предложение).

...