Martijn Burger
Martijn Burger

Reputation: 7543

Can this drools rule be written simpler?

I just started writing drools rules, and came up with this:

rule "Premium to high."
when
    PricingResponse($netPremium : this.getTotalNetPremium(),
                    $paymentTerm : this.getPaymentTerm().getMonths());
    $newPremium : BigDecimal() from $netPremium.multiply($paymentTerm);
    $currentPremium : BigDecimal();
    BigDecimal($newPremium.divide($currentPremium, MathContext.DECIMAL128) > 1.2B);
then
    insert(new Validation("New premium " + $newPremium + " (" + $netPremium +
           " * " + $paymentTerm + ") " + 
           " is larger than 120% of the current premium " +
           $currentPremium, Department.K_EN_A));
end

The drools rule above is working. However, the LHS seems a bit complex for the problem that I am solving, so my question is can it be written simpler? If so, how?

The PricingResponse and a BigDecimal objects are inserted in the KieSession. And after the rules have been fired, all Validation objects are retrieved. A pretty standard rules problem I think. In the PricingResponse object there is a BigDecimal totalNetPremium attribute and a 'PaymentTerm paymentTerm' attribute. I want to validate if the multiplication of paymentTerm and totalNetPremium is larger than 120% of the original premium, which is inserted as the BigDecimal. The PaymentTerm class is and enum, which has a BigDecimal month attribute.

Upvotes: 0

Views: 986

Answers (1)

laune
laune

Reputation: 31290

The rule is indeed unnecessarily complex, mainly because you think you have to extract all BigDecimal objects as patterns. Here is my first proposal:

rule "Premium to high."
when
  PricingResponse($netPrem: totalNetPremium,
                  $paymtTerm: paymentTerm)
  $currPrem: BigDecimal();
  eval( isTooHigh( $netPrem, $paymtTerm.getMonths(), $currPrem ) )
then

Besides omitting the semicolons and the .this.get...() by just using the field names, I have extracted the clumsy BigDecimal operations into a function, which could be implemented as a DRL function or imported as a static Java function.

I dislike the use of "raw" JDK classes as facts (here: BigDecimal). There is no distinction to such objects. This value should come from a containing class such as Policy which, in turn, ought to be linked to PricingResponse.

Upvotes: 1

Related Questions