【问题标题】:Specification Pattern and Boolean Operator Precedence规范模式和布尔运算符优先级
【发布时间】:2011-02-07 21:36:27
【问题描述】:

在我们的项目中,我们使用布尔运算符实现了规范模式(参见 DDD 第 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 isNiceCar = isRed.and(isConvertible).or(isFerrari); Rule isNiceCar2 = isFerrari.or(isRed).and(isConvertible);

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

isRed && isConvertible || isFerrari
相当于
isFerrari || isRed && isConvertible

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

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

OR(isFerrari, AND(isConvertible, isRed))

有人有更好的建议吗?

【问题讨论】:

    标签: operator-precedence specifications specification-pattern


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2012-09-11
      • 2011-12-29
      • 2017-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      • 2020-03-05
      相关资源
      最近更新 更多