在我们的项目中,我们使用布尔运算符实现了规范模式(参见 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))
有人有更好的建议吗?