ir2*_*pid 3 java parameters jboss rule-engine drools
如何在下面的drools规则中传递一个参数来设置age的比较值(18应该是动态的)
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
Run Code Online (Sandbox Code Playgroud)
    对于Drools中的规则,没有什么能比得上"参数传递".规则中使用的数据必须来自工作记忆中的事实或来自全局变量.
使用第一种技术看起来像这样:
rule "AgeCheck"
when
    Parameter( $ageLimit: ageLimit )
    $user: User( age < $ageLimit )
then ... end
Run Code Online (Sandbox Code Playgroud)
Parameter必须首先插入一个类的事实; 它可能包含多个参数.
也可以使用全局变量:
global my.app.Parameter parameter
rule "AgeCheck"
when
    $user: User( age < parameter.getAgeLimit() )
then ... end
Run Code Online (Sandbox Code Playgroud)
有关如何安装全局的详细信息,请参阅专家手册.
为了一点乐趣,我想我会用一个小例子来说明DRL如何通过插入AgeLimit事实来做到这一点.
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
Run Code Online (Sandbox Code Playgroud)
为了进一步减少手摇DRL的数量,您可以AgeLimit使用API 插入这些事实.例如,您可以维护一个包含国家年龄限制的数据库表,并且在会话开始时,您可以将它们全部作为事实插入到工作内存中.或者,您可以创建一个决策表,在后台生成相同的年龄限制插入规则.如果您希望维持每个国家/地区的年龄限制,这可能是管理事物的好方法.
为了使硬编码值保持在关键规则之外的这些目的,有必要阅读推理和真值维护.这可能导致如下规则:
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
Run Code Online (Sandbox Code Playgroud)
这有利于将规则封装在年龄限制附近并提供一些再利用潜力.然而,为了在上面的例子中实现它,涉及IsUnderAge为每个人在其年龄不足的国家插入事实.弄清楚这是否是一件好事会引导我进入各种偏离主题的思维,所以我把它排除在外.:)