Single inheritance in drools

折月煮酒 提交于 2021-01-29 11:55:45

问题


We are using drools 7.31 version. We have one big rule which must be reused in other rules. The basic functionality we need is to fire the SUPER rule when both SUPER rule and SUB rule conditions are true. It seems like older version had "extends" keyword using which this was possible. I was looking at this older post which is able to achieve this -

drools rules inheritance

When I tried on my end with 7.31 version, then both SUPER and SUB rules are firing independently. Here is an example of what I am trying to achieve:

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

The output I am getting is all persons with personId 1/2 of all households first, then then 2nd rule is printing only 99999 household id.

The output that I expect is just to print personId 1/2 of householdId 99999.

Thanks.


回答1:


Drools 7.31 still supports the 'extends' mechanism. The issue here is that when you extend a base rule, the base rule does fire. (This is kind of obvious; if the base rule isn't valid to fire, then the child rule isn't valid to fire. If the base is valid to fire, then it fires. And when the child rule fires, it also fires the parent rule.)

The traditional way to work around this is to use three rules. The "base" rule should have no consequences (that is, no right hand side/then clause) so it simply lists out the common conditions. Then the "super" rule's consequences are in a rule that extends the base rules, doesn't have any additional 'when' conditions, and has the then clause as normal. And the "sub" rule also extends "base", includes its additional conditions, and then its own consequences. If you don't want "super" to fire when "sub" does, you make them mutually exclusive.

Here's an intentionally simplified example:

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

Now if we don't want "Super" to fire when "Sub" does, we just make it mutually exclusive from "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

Basically, when you extend a rule, you're extending both the when and the then clauses. The then clause (consequences) of the parent rule will fire before the consequences of the child rule. Further, if the child is not valid, but the parent is, you will still fire the parent. So if you have (say) 3 child rules and a parent rule, the parent may be fired up to 4 times: once when it by itself is evaluated, and then 3 more times once per child evaluation. Things get particularly odd when you use stateful sessions and update/insert clauses.

The "no consequence" base rule pattern I've shown evolved out of this reality. Following this pattern, it makes no difference how many times "Base Rule" gets fired because there are no side effects (consequences/then clause).



来源:https://stackoverflow.com/questions/61084833/single-inheritance-in-drools

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!