Требуется руководство по проектированию для реализации правил Drools

Я использую в своем приложении Drools 6.1.0.

Мы планируем написать один огромный файл .drl, который будет содержать все правила.

В основном будет 2 категории правил: 1. Проверка на нулевые значения. 2. Бизнес-валидация.

Используя группу потока правил, группу активации и значимость, я планирую управлять тем, какие правила выполнять / запускать при добавлении факта в сеанс.

Даже если с таким подходом решение не работает для меня, потому что.

Допустим, у меня есть файл .drl ниже

rule "rule1"
ruleflow-group "primary"
activation-group "NullCheck"
salience 5
when 
    $m : Message(innerMsg.something == null)
then 
    // do something

rule "rule2"
ruleflow-group "primary"
activation-group "NullCheck"
salience 4
when 
    $m : Message(innerMsg.something.something == null)
then 
    // do something

rule "rule3"
ruleflow-group "primary"
activation-group "NullCheck"
salience 3
when 
    $m : Message(innerMsg.something.something.something == null)
then 
    // do something

В документации Drools сказано: «Все ограничения оцениваются при вставке факта. Из руководства Drools: оценка условия не привязана к определенной последовательности оценки или моменту времени, но происходит постоянно, в любое время в течение срок службы двигателя. "

Итак, что происходит, так это то, что код, выполняющий этот файл, выдает исключение Nullpointer для правила 2, потому что innerMsg.something.something равно NULL

Примечание: я не хочу объединять все нулевые проверки с помощью || в одном операторе when, потому что я хочу зафиксировать конкретное нулевое условие и на его основе создать сообщение об ошибке.

Мои вопросы приведены ниже.

  1. Хорошая идея - использовать правила слюни для проверки Null для связывания объектов.
  2. Должен ли я использовать что-то еще, например, последовательное выполнение правил (не уверен, доступно ли это в Drools), которое позволит мне выполнять правила в определенном порядке.
  3. Есть ли другой способ добиться этого?

person Shantanoo K    schedule 21.05.2015    source источник


Ответы (2)


Чего вы не можете избежать, так это использования нулевой безопасности вашего кода.

Либо вы префикс каждого условия доступа к полю с подтипом Object с нулевым тестом:

Fact( field != null && field.subfield == whatsoever )

или вы используете нулевой безопасный оператор разыменования:

Fact( field!.subfield == whatsoever )

Обратите внимание, что == и != неявно нулевые, так что вы можете написать

Fact( field == whatever )

без проблем если field == null.

Откажитесь от идеи использования группы активации и значимости, чтобы как можно быстрее добиться управления потоком. Это приведет к очень плохому дизайну правил, неподдерживаемому коду и общему недовольству. Если не можете, напишите все на Java или другом языке.

person laune    schedule 22.05.2015
comment
Итак, желательно ли не использовать группу повестки дня / группу потока выполнения и т. Д.? - person Shantanoo K; 22.05.2015
comment
Бывают ситуации, в которых указаны группы повестки дня и значимость, но, на мой взгляд, я не думаю, что их можно найти в вашем заявлении. - person laune; 23.05.2015

Я думаю, что http://drools-moved.46999.n3.nabble.com/rules-users-Drools-Activation-Group-td3546598.html может иметь отношение к тому, что вы видите. Вы можете попробовать что-то вроде следующего.

rule "rule2" ruleflow-group "primary" activation-group "NullCheck" salience 4 when $m : Message(innerMsg != null) Message(this == $m, innerMsg.something != null) Message(this == $m, innerMsg.something.something == null) then

Это работает против вашего желания избежать кучи || в некоторой степени, но это другой синтаксис.

person dew_the_fifth    schedule 21.05.2015
comment
Нет абсолютно никаких причин, по которым нельзя объединять все это в один шаблон, используя && для объединения всех ограничений. Мой ответ на этот вопрос Nabble устарел, так как тем временем в Drools была добавлена ​​нулевая безопасность. - person laune; 22.05.2015