#java #drools
#java #drools
Вопрос:
Я пытаюсь написать что-то подобное с помощью drools, но я не уверен, как это сделать.
У меня есть следующее :
MyData d = new MyData();
MyData d1 = new MyData();
d.setValue(10);
d1.setValue(10);
и это правило, которое я хотел бы реализовать :
rule "data d value equals 10 "
when
d.getValue()==10;
then
doSmthg();
end
если бы я изменил LHS на
$d: MyData(Value ==10)
doSmthg() будет выполняться дважды.
Итак, есть ли способ написать правило только для одного экземпляра вместо всех экземпляров класса MyData??
PS: Мне нужно вставить оба d и d1 в KieSession, потому что у меня есть другие правила, которые включают все экземпляры.
Комментарии:
1. Как предполагается узнать, в каком экземпляре выполнять? Напишите правило, ориентированное на то, что является уникальным.
Ответ №1:
Вам нужно настроить таргетинг на конкретный экземпляр в вашем правиле. Или, если оба элемента одинаковы, и вы просто хотите, чтобы правило срабатывало один раз для данного условия, вы можете вставить флаг или другую конструкцию, чтобы он не запускался несколько раз.
Например, предположим, что у вас есть два MyData со значением = 10. Тот, который вы хотите запустить правилом, также имеет логический флаг latest = true .
Итак, ваша рабочая память имеет:
MyData( value = 10, latest = true ) // we want to trigger the rule with this
MyData( value = 10, latest = false ) // and not this
Затем мы изменим наше правило, чтобы также проверять наличие последнего флага.
rule "Data value is 10, latest"
when
$d: MyData( value == 10, latest == true )
then
$d.doSmthg();
end
В качестве альтернативы, если оба объекта на самом деле одинаковы и в них нет ничего уникального, и мы просто хотим запустить их на основе наличия MyData со значением 10, у вас есть два способа сделать это.
Первый способ — использовать exists
— это просто срабатывает, если в рабочей памяти существует экземпляр, соответствующий этим критериям. Пока вы никогда не переоцениваете правило путем вызова update
, это должно соответствовать вашим потребностям. Однако обратите внимание, что в этом случае у вас нет ссылки на объект.
rule "Any data value with 10 exists"
when
exists( MyData(value == 10) )
then
doSmthg(); // must be function or static import; cannot be instance method
end
Если вам нужно выполнить работу с экземпляром, вы не можете использовать exists и вместо этого должны вставить флаг или иным образом предотвратить повторное срабатывание правила. Самый простой способ — вставить что-то в рабочую память, чтобы действовать как флаг.
rule "Data value is 10, with flag"
when
not( String(this == "DATA_10") ) // if flag does not exist in memory
$d: MyData( value == 10 )
then
$d.doSmthg();
insert( "DATA_10" ); // insert flag
end
Итак, подводя итог, ваши варианты:
- Отключите уникальную характеристику, если это возможно
- Используйте
exists
, если вам не нужна ссылка на экземпляр - Вставьте флаг или другой механизм управления потоком, чтобы правило не запускалось во второй раз.