Pregunta

How can I pass a parameter to set the comparing value of age(18 should be dynamic) in the below drools rule

package com.rule.models

import com.rule.models.User

rule "AgeCheck"
when
    $user: User( age < 18 )
then
    System.out.println("Warning, "+$user.getName()+" is below age!");
end
¿Fue útil?

Solución 2

For a bit of fun I thought I'd knock up a little example DRL demonstrating how this might be done by inserting AgeLimit facts.

declare AgeLimit
    country: String
    age: int
end
declare Bar
    country: String
    revellers: java.util.Collection
end
declare Person
    age: int
end
declare ThrowOutOfTheBar
    person: Person
    bar: Bar
end

rule "UK drinking age" salience 1000 when then
    insertLogical( new AgeLimit( 'uk', 18 ) );
end
rule "US drinking age" salience 1000 when then
    insertLogical( new AgeLimit( 'us', 21 ) );
end

rule "Can I buy a beer?" when
    $p: Person()
    $bar: Bar( revellers contains $p )
    AgeLimit( country == $bar.country, age > $p.age )
then
    insertLogical( new ThrowOutOfTheBar($p, $bar) );
end

To reduce the amount of hand-cranked DRL further, you could insert those AgeLimit facts using the API. For example, you could maintain a database table of national age limits and at the start of your session you could insert them all into working memory as facts. Alternatively, you could create a decision table which generates those same age limit insertions rules behind the scenes. This is likely to be a good way to manage things if for example, you wish to maintain an age limit for every country.

Furthering these ends of keeping hard-coded values out of key rules, it would be worth reading up on inference and truth maintenance. This could lead to a rule such as:

rule "Can I buy a beer?" when
    $p: Person()
    $bar: Bar( revellers contains $p )
    IsUnderAge( person == $p, country == $bar.country )
then
    insertLogical( new ThrowOutOfTheBar($p, $bar) );
end

This has the benefit of encapsulating the rules around age limits and providing some re-use potential. However to achieve it in the example above involves inserting IsUnderAge facts for every person for every country in which they are under age. Working out whether that would be a good thing was leading me into all sorts of off-topic thinking, so I left it out. :)

Otros consejos

For rules in Drools, there is nothing comparable to "parameter passing". Data used in rules must come from facts in Working Memory or from global variables.

Using the first technique would look like this:

rule "AgeCheck"
when
    Parameter( $ageLimit: ageLimit )
    $user: User( age < $ageLimit )
then ... end

A single fact of class Parameter must be inserted initially; it may contain more than one parameter.

Using a global variable is also possible:

global my.app.Parameter parameter

rule "AgeCheck"
when
    $user: User( age < parameter.getAgeLimit() )
then ... end

See the Expert manual for details about how to install a global.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top