Accumulate 的 Drools String 版本

Drools String version of Accumulate

我正在尝试做的事情的基础是从满足特定条件的一组对象中获取一个连接的字符串,其方式与从累积中获取数字总和的方式相同。

下面的规则试图获取任何给定的 IEP 对象并找到属于该 IEP 的所有服务,总结它们的频率持续时间,然后创建每个服务名称的报告并列出每个的持续时间频率。

正确的做法是什么?我的方法是否存在固有的错误,或者我只是遗漏了细微的错误。

dialect  "mvel"

import superObjects.IL.*
import objects.*;
import rules.ValidationHelper;
import java.util.List;
import java.util.ArrayList;

function String serviceDesc(ArrayList sers){
    String s = "";
    for(int i = 0 ; i<sers.size(); i++){
         Super_Service ser = (Super_Service) sers.get(i);             
         s+=ser.getName()+": "+ser.getDuration()*ser.getFrequency()+" Per Week <br>";
     }
     return s;
}

rule "Calculate Service Minutes"
    when
        $siep: Super_Iep();
           $counter : Number() from accumulate(
              $ser: Super_Service(Measurable != "Yes" && ValidationHelper.contains(Documentid, $siep.getIid()+"")),
              sum($ser.getFrequency()*$ser.getDuration())
        );
       $sers: ArrayList() from collect(Super_Service(Measurable != "Yes" && ValidationHelper.contains(Documentid, $siep.getIid()+"")));
    then
        ValidationHelper.storeCalc($siep, $counter, "Text", "SERVICE_MINUTES");
        ValidationHelper.storeCalc($siep, serviceDesc($sers), "Text", "SERVICE_REASON");
end

我不能轻易地包含 ValidationHelper,因为它有数千行代码,但此代码块中的两个函数是一个简单的包含替代项,可以执行其他操作,例如修剪两个字符串,而 storeCalc 只是一个实用函数,用于保存字段到数据库。

你在这里积累和收集的是一个

Map<String,Number> dur2min

即每次服务(和每周)的分钟数。如何从事实中获取数据是业务逻辑的一部分并属于规则,但是 "report" 的组成方式和 呈现方式 (HTML!) 不应该在这里展开,重复选择逻辑 (!) 和收集事实列表的迭代。

我会将两者都移动到一个函数中,该函数在单次迭代中获取列表并计算机器人,

function void serviceDesc(Super_Iep iep, ArrayList sers){
    int sum = 0;
    StringBuilder sb = new StringBuilder();
    for( Object obj: sers ){
        //... add and append
    }
    ValidationHelper.storeCalc( iep, sum, "Text", "SERVICE_MINUTES");
    ValidationHelper.storeCalc( iep, sb.toString(), "Text", "SERVICE_REASON");
}

这是应该在此处还是在 ValidationHelper 本身中还有待讨论,但我宁愿不在 DRL 中。

最后比较结果规则:

rule "Calculate Service Minutes"
when
    $siep: Super_Iep();
    $sers: ArrayList() from collect(Super_Service(Measurable != "Yes" && ValidationHelper.contains(Documentid, $siep.getIid()+"")));
then
    serviceDesc($siep, $sers);
end