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