2

는 우리의 프로젝트에서 우리는과 같이, 부울 연산자 (DDD의 페이지 274 참조)와 사양 패턴을 구현 : 방법 -를 사용하여 규칙의 좋은 표현을 허용사양 패턴 및 부울 연산자 우선 순위

 
public abstract class Rule { 

    public Rule and(Rule rule) { 
     return new AndRule(this, rule); 
    } 

    public Rule or(Rule rule) { 
     return new OrRule(this, rule); 
    } 

    public Rule not() { 
     return new NotRule(this); 
    } 


    public abstract boolean isSatisfied(T obj); 
} 


class AndRule extends Rule { 

    private Rule one; 
    private Rule two; 

    AndRule(Rule one, Rule two) { 
     this.one = one; 
     this.two = two; 
    } 

    public boolean isSatisfied(T obj) { 
     return one.isSatisfied(obj) && two.isSatisfied(obj); 
    } 
} 

class OrRule extends Rule { 

    private Rule one; 
    private Rule two; 

    OrRule(Rule one, Rule two) { 
     this.one = one; 
     this.two = two; 
    } 

    public boolean isSatisfied(T obj) { 
     return one.isSatisfied(obj) || two.isSatisfied(obj); 
    } 
} 

class NotRule extends Rule { 

    private Rule rule; 

    NotRule(Rule obj) { 
     this.rule = obj; 
    } 

    public boolean isSatisfied(T obj) { 
     return !rule.isSatisfied(obj);     
    } 
} 

체인 연결을 지원하지만, 이 미묘한 오류를 유발할 수있는 표준 작동 우선 순위 규칙을 지원하지 않습니다.

다음과 같은 규칙

은 해당되지 않습니다

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

가 논리 값이라면

isRed && isConvertible || isFerrari
isFerrari || isRed && isConvertible

에 상응하는 것이기 때문에 혼란 스러울 수 있습니다 차량이없는 컨버터블의 경우 isNiceCar2을 만족하지 규칙,

isFerrari.or (isRed.and (isConvertible))가되도록 isNiceCar2를 다시 작성하면 둘 다 동일하다는 것을 알고 있지만 둘 다 구문 적으로 정확합니다.

우리가 가지고 올 수있는 가장 좋은 방법은 메소드 체인을 금지하는 것입니다, 대신 사용 생성자 :

 
OR(isFerrari, AND(isConvertible, isRed)) 

사람이 더 나은 제안이 있습니까?

답변

2

"생성자"솔루션은 체인보다 표현식 트리에 더 가까운 무언가를 만들어야한다는 점에서 의미가 있습니다. 또 다른 솔루션은 평가 기능을 Rule 구현에서 끌어내어 우선 순위를 적용 할 수 있도록하는 것입니다 (체인을 걷음으로써).