2

在我们的项目中,我们使用布尔运算符实现了规范模式(参见 DDD p 274),如下所示:

公共抽象类规则{

    公共规则和(规则规则){
        返回新的 AndRule(this, rule);
    }

    公共规则或(规则规则){
        返回新的 OrRule(this, rule);
    }

    公共规则不(){
        返回新的 NotRule(this);
    }


    公共抽象布尔 isSatisfied(T obj);
}


类 AndRule 扩展规则 {

    私人规则一;
    私人规则二;

    AndRule(规则一,规则二){
        this.one = 一;
        this.two = 二;
    }

    公共布尔isSatisfied(T obj){
        return one.isSatisfied(obj) && two.isSatisfied(obj);
    }
}

类 OrRule 扩展规则 {

    私人规则一;
    私人规则二;

    OrRule(规则一,规则二){
        this.one = 一;
        this.two = 二;
    }

    公共布尔isSatisfied(T obj){
        返回一个.isSatisfied(obj) || 二.isSatisfied(obj);
    }
}

类 NotRule 扩展规则 {

    私有规则规则;

    NotRule(规则 obj){
        this.rule = obj;
    }

    公共布尔isSatisfied(T obj){
        返回 !rule.isSatisfied(obj);                
    }
}

这允许使用方法链很好地表达规则,但它不支持可能导致细微错误的标准运算符优先规则。

以下规则不等效:

Rule<Car> isNiceCar = isRed.and(isConvertible).or(isFerrari);
Rule<Car> isNiceCar2 = isFerrari.or(isRed).and(isConvertible);

如果汽车不是敞篷车,则不满足规则isNiceCar2 ,这可能会令人困惑,因为如果它们是布尔值

isRed && isConvertible || 是法拉利
相当于
是法拉利|| isRed && isConvertible

我意识到如果我们将 isNiceCar2 重写为 isFerrari.or(isRed.and(isConvertible)),它们将是等价的,但两者在语法上都是正确的。

我们能想到的最佳解决方案是取缔方法链,并改用构造函数:

OR(isFerrari, AND(isConvertible, isRed))

有人有更好的建议吗?

4

1 回答 1

2

您的“构造函数”解决方案听起来是正确的(至少在语义上),因为它强制构建更接近表达式树而不是链的东西。另一种解决方案是将评估功能从规则实现中提取出来,以便可以强制执行优先级(通过遍历链)。

于 2010-04-14T12:40:00.303 回答