Search code examples
javadroolsmvel

Drools - Best practices for comparing fields not involving primary datatypes


Is there a better way to define the follow rule?

Following rule checks to see if a person is Overweight (by calling the greaterThan method defined in the Weight class).

Rule:

rule "OverWeightTest"
 dialect "mvel"
 when
    $person : Person(weight.greaterThan(new Weight(200, Weight.Unit.LBS)) )
 then
    System.out.println($person + " is overweight!");
end

Java Classes:

public class Person
{
    private final String name;
    private final Weight weight;
}

public class Weight
{
    private final int value;
    private final Unit unit;

    public boolean greaterThan(final Weight otherWeight) {
       ...
    }
}
  • I'd rather not use Globals for the constant "200 LBS". Mainly because I want the rule author to mention the weight limit and I don't want to burden the application with it.
  • "200 LBS" **instantiated in-line. I'd like to separate it out to a different line, so that the rule is more readable. How do I do that?
  • What's the recommended way to compare fields that don't involve primary datatypes (int, boolean, float, double, etc). In this particular example, it's Weight.

Thanks!!


Solution

  • Even if @Laune's answer is the most clean and follows all the best practices, I'll leave this alternative way you have to instantiate objects in the LHS of your rules (maybe because some of the necessary parameters in the constructor comes from a variable bound to a fact).

    rule "OverWeightTest"
    dialect "mvel"
    when
        $w: Weight() from new Weight(200, Weight.Unit.LBS)
        $person : Person( weight.greaterThan($w) )
    then
        System.out.println($person + " is overweight!");
    end
    

    Again, I do agree that the rule above will be considered an unholy monstrosity by production rule systems purists!

    Hope it helps,