お題は、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 件のコメント:
コメントを投稿