2

私たちのプロジェクトでは、次のようにブール演算子を使用して仕様パターンを実装しました (DDD p 274 を参照)。

パブリック抽象クラス ルール {

    public Rule and(Rule rule) {
        新しいAndRule(これ、ルール)を返します。
    }

    パブリック ルール or(ルール ルール) {
        新しい OrRule(これ、ルール) を返します。
    }

    公の規則 not() {
        新しい NotRule(this) を返します。
    }


    public abstract boolean isSatisfied(T obj);
}


クラス AndRule はルールを拡張します {

    プライベート ルール 1;
    プライベート ルール 2。

    AndRule(ルール 1、ルール 2) {
        this.one = 1;
        this.two = 2;
    }

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

クラス OrRule はルールを拡張します {

    プライベート ルール 1;
    プライベート ルール 2。

    OrRule(ルール 1、ルール 2) {
        this.one = 1;
        this.two = 2;
    }

    public boolean isSatisfied(T obj) {
        one.isSatisfied(obj) を返します || 2.isSatisfied(obj);
    }
}

クラス NotRule はルールを拡張します {

    プライベート ルール ルール。

    NotRule(ルール オブジェクト) {
        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);

車がコンバーチブルでない場合、規則isNiceCar2は満たされません。

isRed && isConvertible || はフェラーリ
と同等です
|| はフェラーリ || isRed && isConvertible

isNiceCar2 を isFerrari.or(isRed.and(isConvertible)) に書き直せば同等になることはわかっていますが、どちらも構文的には正しいです。

私たちが思いつく最善の解決策は、メソッドチェーンを禁止し、代わりにコンストラクターを使用することです。

OR(isFerrari, AND(isConvertible, isRed))

誰かがより良い提案をしていますか?

4

1 に答える 1

2

あなたの「コンストラクター」ソリューションは、チェーンよりも式ツリーに近いものを構築することを強制するという点で、(少なくとも意味的には) 正しいように聞こえます。もう 1 つの解決策は、(チェーンをたどることによって) 優先順位を適用できるように、ルールの実装から評価機能を引き出すことです。

于 2010-04-14T12:40:00.303 に答える