我是流口水的新手,我写了一些规则,他们按预期工作。但是,我不禁想到有更简洁的方式来编写这些规则。
我的情况是,许多规则都有一些类似的基本要求,我在每条规则中重复这些要求。因此,例如,假设我有以下规则:
rule "Main Valid Message"
when Account (open && valid)
then myResults.add(new Message("Your account is valid"))
end
rule "The user owns something Message"
when Account (ownership.size() >= 1)
then myResults.add(new Message("You own something"))
end
rule "Eligibility Message"
when
Account (open && valid)
Account (ownership.size() >= 1)
then myResults.add(new Message("You are eligible"))
end
有没有办法重写资格规则以利用前两条规则而不是复制其内容?
答案:结合使用J Andy和laune的回复,我写了如下:
declare IsValid
account : Account
end
declare OwnsSomething
account : Account
end
rule "Main Valid Message"
when $account : Account (open && valid)
then
myResults.add(new Message("Your account is valid"))
insertLogical(new IsValid($account));
end
rule "The user owns something Message"
when $account : Account (ownership.sizeOwnsSomething() >= 1)
then
myResults.add(new Message("You own something"))
insertLogical(new OwnsSomething($account));
end
rule "Eligibility Message"
when
IsValid()
OwnsSomething()
then myResults.add(new Message("You are eligible"))
end
答案 0 :(得分:3)
然后有可能扩展规则,允许您将一个规则的条件继承到任意数量的其他规则:
rule "multiple account owners"
when
$acc: Account( owners.size() > 1 )
then end
rule "multiple and open and valid"
extends "multiple account owners"
when
Account( this == $acc, open && valid )
then
如果您遵循Andy的想法,请考虑使用insertLogical和对相关帐户的引用(除非您一次调查一个帐户事实):
rule "multiple account owners"
when
$acc: Account( owners.size() > 1 )
then
insertLogical( new Multiple( $acc ) );
end
小心这种方法,以免过早地使用由辅助事实表示的属性的否定(!)形式引发规则,例如,
rule "funny account"
when
$acc : Account( balance > 10000000 ) # can have more than one owner
not Multiple( account == $acc )
then ... end
这可以在“多个帐户所有者”声明“多个”之前触发,除非该规则具有更高的显着性。此外,请注意通过插入辅助事实来评估所有这些属性的效果:无论如何都会创建此开销,即使某个帐户不需要它们以便进行处理。
最后,还有一个适用于帐户的适配器(或包装器)的想法,为帐户提供任意数量的花哨的getter:
rule "wrap account"
when $acc: Account() not Wrapper( account == $acc )
then insert( new Wrapper( $acc ) end
rule "multiple valid-open"
when Wrapper( multiple && validOpen )
then ... end
当然,您可以使用DRL功能:
function boolean multiOwners( Account account ){
return account.getOwners().size() > 1;
}
rule "multi valid open"
when $acc: Account( eval( multiOwners($acc) && openValied($acc) ) )
then ... end
(我不确定你是否需要最新的Drools版本中的eval。)
答案 1 :(得分:1)
一种选择是使用(内部)事实来处理状态。像这样的东西
declare AuthenticatedUser
end
rule "Authenticate user"
when
Account( open && valid )
then
insert( new AuthenticatedUser() );
end
rule "Eligibility Message"
when
AuthenticatedUser()
then
myResults.add( new Message( "You are eligible" ) );
end
我不确定您的帐户所有权用例是什么,但我认为您可以从上面的代码示例中获得重点。
AuthenticatedUser
事实现在在DRL文件中声明。它也可以是正常的Java类。此外,在示例中它根本没有属性,但如前所述,它甚至可以保存一些您在规则中修改的状态。