隱藏策略實施細節

物件導向設計中一個非常常見的指導原則是儘可能少但必要時。這也適用於策略模式:通常建議隱藏實現細節,例如哪些類實際實現策略。

對於不依賴於外部引數的簡單策略,最常見的方法是使實現類本身為私有(巢狀類)或包私有,並通過公共類的靜態欄位公開例項:

public class Animal {

  private static class AgeComparator implements Comparator<Animal> {
    public int compare(Animal a, Animal b) {
      return a.age() - b.age();
    }
  }

  // Note that this field has the generic type Comparator<Animal>, *not*
  // Animal.AgeComparator!
  public static final Comparator<Animal> AGE_COMPARATOR = new AgeComparator();

  private final int age;

  Animal(int age) {
    this.age = age;
  }

  public int age() {
    return age;
  }

}

List<Animal> myList = new LinkedList<>();
myList.add(new Animal(10));
myList.add(new Animal(5));
myList.add(new Animal(7));
myList.add(new Animal(9));

Collections.sort(
  myList,
  Animal.AGE_COMPARATOR
);

公共欄位 Animal.AGE_COMPARATOR 定義了一個策略,然後可以在 Collections.sort 等方法中使用,但它不需要使用者知道任何有關其實現的資訊,甚至不需要知道實現類。

如果你願意,可以使用匿名類:

public class Animal {

  public static final Comparator<Animal> AGE_COMPARATOR = new Comparator<Animal> {
    public int compare(Animal a, Animal b) {
      return a.age() - b.age();
    }
  };

  // other members...
}

如果策略稍微複雜並且需要引數,則使用靜態工廠方法(例如 Collections.reverseOrder(Comparator<T>) 是很常見的。該方法的返回型別不應暴露任何實現細節,例如 reverseOrder() 的實現方式

public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
  // (Irrelevant lines left out.)
  return new ReverseComparator2<>(cmp);
}