お題は、DDD でよく使われる Specification Pattern にしてみよう。Wikipediaのこのエントリに、C#で書かれたコードが載ってるので、ざっと書き換えてみよう。
interface Specification<t> {
boolean isSatisfiedBy(T t);
default Specification<t> and(Specification<t> other) {
assert other != null;
return t -> this.isSatisfiedBy(t) && other.isSatisfiedBy(t);
}
default Specification<t> or(Specification<t> other) {
assert other != null;
return t -> this.isSatisfiedBy(t) || other.isSatisfiedBy(t);
}
default Specification<t> not() {
return t -> !isSatisfiedBy(t);
}
}
だいたいこんな感じになる。元のコードよりだいぶ簡単になった。試しに動かしてみるコードが以下。
public class Test {
public static void main(String[] args) {
Specification<String> shortString = s -> s.length() < 3;
Specification<String> startsWithA = s -> s.length() > 0 && s.charAt(0) == 'a';
System.out.println(shortString.not().isSatisfiedBy("bcdefg"));// true
System.out.println(shortString.and(startsWithA).isSatisfiedBy("bc"));// false
System.out.println(shortString.or(startsWithA).isSatisfiedBy("bc"));// true
}
}
実は、この Specificationと同じような Predicate というインターフェイスが、すでに java.util.function パッケージ配下にあったりする。ただ、単なる predicate(述語) というよりもっと具体的に specification(仕様)という意味で使う文脈だと、やはり test() より isSpecifiedBy() の方が良いし(Evans と Fowler の元の記事でもそうなってる)、negate() より not() の方がいいように思う。
0 件のコメント:
コメントを投稿