私たちのプロジェクトでは、次のようにブール演算子を使用して仕様パターンを実装しました (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))
誰かがより良い提案をしていますか?