Guava中的Utility Object Pattern
在一篇Guava的presentation中,Google提到了一种叫“Utility Object pattern”的模式。
return Joiner.on(", ").skipNulls().join("one", null, "two", "three");
|-- 1 ---|-- 2 ------|-- 3 ----------------------------|
return Splitter.on("|").omitEmptyStrings().split("|Harry||Ron|||Hermione ||");
|-- 1 --|-- 2 -------------|-- 3 ------------------------------|
通过1
得到一个初始的、默认的utility对象,通过2
可以得到utility对象的一个“变种”,
再通过3
最后求值。
这种API看起来更简洁。用户不用知道不同变种对应的utility类。
实现上,2
中的方法,比如skipNulls()
,会返回一个新对象,或者修改对象的属性并返回它。
public Joiner skipNulls() {
return new Joiner(this) {//通过传入的this可以“继承”上一个Utility对象的某些特性
@Override
public <A extends Appendable> A appendTo(A appendable, Iterator<?> parts) throws IOException {
//...
}
//...
}
}
public Splitter omitEmptyStrings() {
//直接构造相应的Utility对象
return new Splitter(strategy, true, trimmer, limit);
}
ComparisonChain是另一个有趣的例子。
Comparator<Person> comparator = new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return ComparisonChain.start().compare(p1.exp, p2.exp).compare(p1.age, p2.age).result();
}
};
使用ComparisonChain时,不会创建新的ComparisonChain对象。
ComparisonChain也支持“short circuit(短路)”。
当p1.exp
和p2.exp
的比较有结果时(不等于0),就不会再去比较age
。
...