隱藏策略實施細節
物件導向設計中一個非常常見的指導原則是儘可能少但必要時。這也適用於策略模式:通常建議隱藏實現細節,例如哪些類實際實現策略。
對於不依賴於外部引數的簡單策略,最常見的方法是使實現類本身為私有(巢狀類)或包私有,並通過公共類的靜態欄位公開例項:
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);
}