C/C++ 通過函數指針傳遞行為,Java 無指針機制,但可用函數對象(Function Object)實現同樣效果:定義一個類,其實例方法封裝具體演算法,再將實例作為參數傳遞。
步驟 1:具體策略類
class StringLengthComparator {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
步驟 2:單例優化(無狀態策略)
public class StringLengthComparator implements Comparator<String> {
private StringLengthComparator() {}
public static final StringLengthComparator INSTANCE = new StringLengthComparator();
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
步驟 3:定義策略接口(Java 已內建 java.util.Comparator<T>)
public interface Comparator<T> {
int compare(T t1, T t2);
}
| 場景 | 寫法 | 優缺點 |
|---|---|---|
| 一次性使用 | 匿名類Arrays.sort(arr, new Comparator<>() {...}) | 簡潔但每次調用創建新實例 |
| 重複使用、無序列化需求 | 私有靜態成員類 + 公開靜態 final 域private static class StrLenCmp implements Comparator<String> {...} | 單例複用、命名清晰、可實現多接口 |
| 需序列化/跨進程傳遞 | 成員類實現 Serializable | 保持策略對象可序列化 |
public class Host {
private static class StrLenCmp implements Comparator<String>, Serializable {
public int compare(String s1, String s2) { return s1.length() - s2.length(); }
}
public static final Comparator<String> STRING_LENGTH_COMPARATOR = new StrLenCmp();
}
要點:策略接口作為類型參數,具體策略類封裝於宿主類內部,對外僅暴露接口類型常量,體現「封裝變化」原則。
Java 中實現策略模式:聲明策略接口 → 實現具體策略類 → 以接口類型傳遞/持有。一次性用匿名類,重用用私有靜態成員類 + 公開常量導出。這正是 String.CASE_INSENSITIVE_ORDER 等標準庫的實現方式。