首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Drools规则引擎中的列表

使用Drools规则引擎中的列表
EN

Stack Overflow用户
提问于 2021-08-04 20:00:23
回答 1查看 367关注 0票数 1

我正试着用口水来处理列表。我正在传递一个请求,其中包含了一个购买清单。我想做几个规则,包括检查大小是否正确,如果所有元素是相同的,如果所有购买都是授权的,.我有下面的代码,但是我在处理列表时遇到了问题。这样做对吗?尤其是在检查尺寸的时候?

代码语言:javascript
复制
import com.rules.Purchase
import com.rules.PurchaseRequest

dialect  "mvel"

global Boolean eligibleForRefund

rule "Check for list not equal to two elements" salience 10
    when
        PurchaseRequest(getPurchases != null, getPurchases.size() != 2)

    then
        drools.getKieRuntime().setGlobal("eligibleForRefund", false);
end

rule "Check for two purchases" salience 9
    when:
        $purchaseRequest: PurchaseRequest()
        Number(intValue != 2) from accumulate(Purchase(getStatus() == "Approved") from $purchaseRequest.getPurchases(), count(1))

    then
        drools.getKieRuntime().setGlobal("eligibleForRefund", false);
end

rule "Check for the same purchases" salience 8
    when:
        $purchaseRequest: PurchaseRequest()

    then
        firstPurchase = $purchaseRequest.getPurchases().get(0).getCost();
        hasAllElements = true;

        for (Purchase purchase : $purchaseRequest.getPurchases()) {
            if (purchase.getCost() != firstPurchase) {
                hasAllElements = false;
            }
        }

        drools.getKieRuntime().setGlobal("eligibleForRefund", hasAllElements);
end
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-04 20:59:42

假设类定义如下所示:

代码语言:javascript
复制
class PurchaseRequest {
  private List<Purchase> purchases;
  
  public List<Purchase> getPurchases() { return this.purchases; }
}

您应该从持有者中提取引用,而不是通过getter不断地与事物交互。在其他项目中,这有助于保持数据的一致性,特别是与共享资源一致。回想一下,如果您有一个名与getXyz格式匹配的getter,您可以简单地将其称为xyz,drools将自动地将其映射到getter函数。这允许我们通过PurchaseRequest( $purchases: purchases )获得购买,因为purchases将映射到getPurchases()。(请注意,如果购买碰巧是一个公共变量,那么它应该首先映射到该变量;但是由于它是私有的,所以它回到了遵循bean命名约定的公共getter上。)

其次,在一个非常简单的场景中使用accumulate,其中collect可能更合适。通常,对于更复杂的“获取类似于此的东西”的情况,您可以使用accumulate;但是对于简单的匹配,集合也同样有效。

第三条规则需要做的工作最多。您不希望在规则的右侧执行这种业务逻辑。有很多方法可以用来检查所有元素是否都是相同的--如果您已经实现了等于/hashCode,您可以将所有内容都插入到一个集合中,并确认集合的长度仍然是列表的长度;您可以倒转规则来检查至少一个不同的项;您可以使用累积或收集;

最后--

  • 避免突出。他们的设计很糟糕。你的规则应该是独立的。您只需要突出说明,因为您的第三条规则同时设置了正确和错误。如果您默认为true,然后使用规则将其重写为false,则完全没有显着性就可以幸免。
  • 为全局变量使用原语是非常不寻常的。坦率地说,我不相信这对于一个原始的人来说是可行的。Globals之所以工作,是因为对象是通过引用传入的,并在规则中更新,因此保留对对象的引用的调用方将获得更新的值。这不适用于原语。

代码语言:javascript
复制
rule "Check for list not equal to two elements" 
salience 1
when
  PurchaseRequest($purchases: purchases != null)
  List(size != 2) from $purchases
then
  drools.getKieRuntime().setGlobal("eligibleForRefund", false);
end

rule "Check for two purchases"
salience 1
when:
  PurchaseRequest( $purchases: purchases != null)
  List( size != 2 ) from collect( Purchase(status == "Approved") from $purchases)
then
  drools.getKieRuntime().setGlobal("eligibleForRefund", false);
end

// I've no idea what data type `getCost()` returns; I'm assuming "String"
rule "Check for the same purchases"
when:
  PurchaseRequest($purchases: purchases != null)

  // accumulate all of the costs into a set. if all costs are the same, set size = 1
  $costs: Set() from accumulate( Purchase( $cost: cost ) from $purchases;
                                 collectSet($cost))
then
  drools.getKieRuntime().setGlobal("eligibleForRefund", $costs.size() == 1);
end
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68657387

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档