我正在开发一个 drools 项目,其中每个.drl
文件都是从velocity template
. then
我已经编写了在.drl
文件本身中成功检查条件后要执行的每个计算和操作。
让我们假设一个简单的条件
rule "Rule %"
no-loop
salience 10
when
$var: Map( this["Key"] == "SomeValue" )
then
$var.put("Discount%", Do-SOME-%-CALCULATION AND PUT IT HERE)
end
rule "Rule Amt"
no-loop
salience 9
when
$var: Map( this["Key"] == "SomeValue" )
then
$var.put("DiscountAmt", Do-SOME-Amt-CALCULATION AND PUT IT HERE)
end
rule "Rule % Amt"
no-loop
salience 8
when
$var: Map( this["Key"] == "SomeValue" )
then
$var.put("Discount%", Do-SOME-%-CALCULATION AND PUT IT HERE)
$var.put("DiscountAmt", Do-SOME-Amt-CALCULATION AND PUT IT HERE)
end
为了形成这些类型的 DRL 文件,我形成了velocity template like this
#set($d = "$")
rule "$rule.name $rule.type"
no-loop
salience $rule.priority
when
${d}var: Map( this["$rule.keyName"] == "$rule.keyValue" )
then
#if( $rule.type == "%" )
${d}var.put("Discount%", CODE-FOR-%-CALCULATION);
#elseif( $rule.type == "Amt" )
${d}var.put("DiscountAmt", CODE-FOR-AMT-CALCULATION);
#elseif( $rule.type == "% Amt" )
${d}var.put("Discount%", CODE-FOR-%-CALCULATION);
${d}var.put("DiscountAmt", CODE-FOR-AMT-CALCULATION);
#end
我知道#elseif( $rule.type == "% Amt" )
可以通过利用前两个并同时满足这两个条件来消除最后if
一个。但这只是一个例子。elseif
|| $rule.type == "% Amt"
假设我没有任何选择将这 3 个条件简化为 2 个条件,而是重复我的代码本身。相信我,我有更多的计算,我必须在速度代码中重复这些代码多种类型。这变得一团糟。因为,如果我必须在公式中做一个小的改动,我必须对速度模板中的所有重复代码进行更改,如果我们错过了重复代码中的更改,这肯定会导致人为错误。
这就是为什么我想在 Java 类中编写这些公式和计算,并简单地在.drl
. 所以.drl
和.vm
在.drl
import com.package.util.RuleUtil;
rule "Rule %"
no-loop
salience 10
when
$ruleUtil: RuleUtil()
$var: Map( this["Key"] == "SomeValue" )
then
$ruleUtil.discountPer($var);
end
rule "Rule Amt"
no-loop
salience 9
when
$ruleUtil: RuleUtil()
$var: Map( this["Key"] == "SomeValue" )
then
$ruleUtil.discountAmt($var);
end
rule "Rule % Amt"
no-loop
salience 8
when
$ruleUtil: RuleUtil()
$var: Map( this["Key"] == "SomeValue" )
then
$ruleUtil.discountPer($var);
$ruleUtil.discountAmt($var);
end
在.vm
#set($d = "$")
rule "$rule.name $rule.type"
no-loop
salience $rule.priority
when
${d}ruleUtil: RuleUtil()
${d}var: Map( this["$rule.keyName"] == "$rule.keyValue" )
then
#if( $rule.type == "%" )
${d}ruleUtil.discountPer(${d}var);
#elseif( $rule.type == "Amt" )
${d}ruleUtil.discountAmt(${d}var);
#elseif( $rule.type == "% Amt" )
${d}ruleUtil.discountPer(${d}var);
${d}ruleUtil.discountAmt(${d}var);
#end
如果您想知道我重复了多少次折扣公式代码,我会说至少 10 次,并且对于多种类型的折扣计算涉及更多的重复。TBH,我在看.vm
代码时很生气。由于所有这些代码重复和长期的可维护性差。我想知道是否坚持使用当前代码(当前 vm 代码涉及多个代码重复且难以维护)或者我是否应该通过实现我提出的结构将所有这些公式计算移至 Java 方法。我不知道它会对我的.drl
文件性能产生多大影响。任何建议将不胜感激。
注意:我最喜欢代码可维护性。我不希望有人在他接手这个项目后打破他的脑袋。当然,我也不想在做任何小的改变时伤脑筋。