можно ли писать правила для экземпляров, а не для классов в drools?

#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
  

Итак, подводя итог, ваши варианты:

  1. Отключите уникальную характеристику, если это возможно
  2. Используйте exists , если вам не нужна ссылка на экземпляр
  3. Вставьте флаг или другой механизм управления потоком, чтобы правило не запускалось во второй раз.