在Drools中,是否可以针对实例而不是类编写规则?

huangapple go评论72阅读模式
英文:

is it possible to write rules on instances rather than classes in 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类的一个实例编写规则,而不是所有MyData类的实例?

PS:我需要将d和d1都插入kieSession,因为我有其他涉及所有实例的规则。

英文:

I am trying to write something like this with drools but I am not sure how to go about it.

I have the following :

MyData d = new MyData();
MyData d1 = new MyData();
d.setValue(10);
d1.setValue(10);

and this is the rule I would like to implement :

rule "data d value equals 10 "
when
	d.getValue()==10;
then
doSmthg();
end

if I were to change the LHS to

$d: MyData(Value ==10) 

the doSmthg() would be executed twice.

So is there a way to write the rule only about one instance instead of all the instances of the MyData class??

PS: I need to insert both d and d1 in the kieSession because I have other rules that involve all the instances.

答案1

得分: 1

你需要针对规则中的特定实例进行操作。或者如果两个项目相同,你只希望在给定条件下触发规则一次,你可以插入一个标志或其他构造来阻止它多次触发。

例如,假设你有两个值都为10的MyData。你希望触发规则的一个还具有一个布尔标志latest = true。

因此,你的工作内存中有:

MyData( value = 10, latest = true ) // 我们希望触发此规则
MyData( value = 10, latest = false ) // 不希望触发此规则

然后我们会修改我们的规则以检查latest标志。

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(); // 必须是函数或静态导入;不能是实例方法
end

如果你需要针对实例执行操作,就不能使用exists,而必须插入一个标志或以其他方式阻止规则再次触发。最简单的方法是将某些内容插入到工作内存中,以充当标志。

rule "Data value is 10, with flag"
when
  not( String(this == "DATA_10") ) // 如果内存中不存在标志
  $d: MyData( value == 10 )
then
  $d.doSmthg();
  insert( "DATA_10" ); // 插入标志
end

总结一下,你的选择是:

  1. 如果可能的话,以唯一特征作为关键。
  2. 如果不需要实例引用,可以使用exists
  3. 插入标志或其他流程控制机制,以防止规则第二次触发。
英文:

You need to target the specific instance in your rule. Or if both items are the same and you just want the rule to fire once for a given condition, you can insert a flag or other construct to keep it from firing multiple times.

For example, let's say that you have two MyData with value = 10. The one you do want to fire the rule also has a boolean flag latest = true.

So your working memory has:

MyData( value = 10, latest = true ) // we want to trigger the rule with this
MyData( value = 10, latest = false ) // and not this

Then we'd modify our rule to also check for the latest flag.

rule "Data value is 10, latest"
when
  $d: MyData( value == 10, latest == true )
then
  $d.doSmthg();
end

Alternatively if both objects are actually the same and there's nothing unique about them, and we just want to trigger based on the presence of a MyData with value 10, you have two ways to do this.

The first way is to use exists -- this just fires if there exists an instance in working memory that meets this criteria. As long as you never re-evaluate the rule by calling update, this should suit your needs. Note however that you have no reference to the object in this case.

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

If you do need to do work against the instance, you can't use exists and instead have to insert a flag or otherwise keep the rule from firing again. Easiest way is to insert something into working memory to act as a flag.

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

So to summarize, your options are:

  1. Key off of a unique characteristic if possible
  2. Use exists if you don't need an instance reference
  3. Insert a flag or other flow control mechanism to keep the rule from firing a second time.

huangapple
  • 本文由 发表于 2020年9月24日 01:45:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/64033551.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定