流氓需要多个其他规则的规则

时间:2013-12-10 19:10:01

标签: drools rule-engine

我是流口水的新手,我写了一些规则,他们按预期工作。但是,我不禁想到有更简洁的方式来编写这些规则。

我的情况是,许多规则都有一些类似的基本要求,我在每条规则中重复这些要求。因此,例如,假设我有以下规则:

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

2 个答案:

答案 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类。此外,在示例中它根本没有属性,但如前所述,它甚至可以保存一些您在规则中修改的状态。