在一篇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.expp2.exp的比较有结果时(不等于0),就不会再去比较age

public abstract class ComparisonChain {
  private ComparisonChain() {}

  public abstract ComparisonChain compare(Comparable<?> left, Comparable<?> right);
  public abstract <T> ComparisonChain compare(
    @Nullable T left, @Nullable T right, Comparator<T> comparator);
  public abstract ComparisonChain compare(int left, int right);
  // ...
    
  public static ComparisonChain start() {
    return ACTIVE;
  }

  private static final ComparisonChain ACTIVE =
    new ComparisonChain() {
      @Override
      public ComparisonChain compare(Comparable left, Comparable right) {
        return classify(left.compareTo(right));
      }

      @Override
      public <T> ComparisonChain compare(
        @Nullable T left, @Nullable T right, Comparator<T> comparator) {
        return classify(comparator.compare(left, right));
      }

      @Override
      public ComparisonChain compare(int left, int right) {
        return classify(Ints.compare(left, right));
      }

      ComparisonChain classify(int result) {
        return (result < 0) ? LESS : (result > 0) ? GREATER : ACTIVE;
      }

      @Override
      public int result() { return 0;}
    };


  private static final ComparisonChain LESS = new InactiveComparisonChain(-1);
  private static final ComparisonChain GREATER = new InactiveComparisonChain(1);

  private static final class InactiveComparisonChain extends ComparisonChain {
    final int result;

    InactiveComparisonChain(int result) { this.result = result; }

    @Override
    public ComparisonChain compare(@Nullable Comparable left, @Nullable Comparable right) {
      // 不会做任何比较运算,直接返回自己
      return this;
    }

    @Override
    public ComparisonChain compare(int left, int right) { return this; }

    @Override
    public int result() { return result; }
  }

ComparisonChain定义了3个静态变量,ACTIVELESSGREATER。 所有的比较都基于这3个对象,不会新建新的ComparisonChain对象。 只有ACTIVE会做真正的比较。一旦ACTIVE有了比较结果,就会返回LESS或者GREATER对象。 后续的比较都会基于LESS或者GREATER,它们不会做任何比较运算(这就是某种意义上的“短路”)。