定義
定義一系列算法類,將每一個算法封裝起來,並讓它們可以相互替換,策略模式讓算法獨立於使用它的客戶而變化,也稱爲政策模式(Policy)。策略模式是一種對象行爲型模式。
UML類圖
代碼實現
Strategy.java
public abstract class Strategy {
public abstract void algorithm();
}
Context.java
public class Context {
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void algorithm() {
strategy.algorithm();
}
}
ConcreteStrategyA.java
public class ConcreteStrategyA extends Strategy {
@Override
public void algorithm() {
System.out.println("ConcreteStrategyA algorithm");
}
}
ConcreteStrategyB.java
public class ConcreteStrategyB extends Strategy {
@Override
public void algorithm() {
System.out.println("ConcreteStrategyB algorithm");
}
}
Main.java
Context context = new Context();
Strategy strategyA = new ConcreteStrategyA();
Strategy strategyB = new ConcreteStrategyB();
context.setStrategy(strategyA);
context.algorithm();
context.setStrategy(strategyB);
context.algorithm();
打印結果:
ConcreteStrategyA algorithm
ConcreteStrategyB algorithm
優缺點
主要優點
-
策略模式提供了對“開閉原則”的完美支持,用戶可以在不修改原有系統的基礎上選擇算法或行爲,也可以靈活地增加新的算法或行爲。
-
策略模式提供了管理相關的算法族的辦法。策略類的等級結構定義了一個算法或行爲族,恰當使用繼承可以把公共的代碼移到抽象策略類中,從而避免重複的代碼。
-
策略模式提供了一種可以替換繼承關係的辦法。如果不使用策略模式,那麼使用算法的環境類就可能會有一些子類,每一個子類提供一種不同的算法。但是,這樣一來算法的使用就和算法本身混在一起,不符合“單一職責原則”,決定使用哪一種算法的邏輯和該算法本身混合在一起,從而不可能再獨立演化;而且使用繼承無法實現算法或行爲在程序運行時的動態切換。
-
使用策略模式可以避免多重條件選擇語句。多重條件選擇語句不易維護,它把採取哪一種算法或行爲的邏輯與算法或行爲本身的實現邏輯混合在一起,將它們全部硬編碼(Hard Coding)在一個龐大的多重條件選擇語句中,比直接繼承環境類的辦法還要原始和落後。
-
策略模式提供了一種算法的複用機制,由於將算法單獨提取出來封裝在策略類中,因此不同的環境類可以方便地複用這些策略類。
主要缺點
-
客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。這就意味着客戶端必須理解這些算法的區別,以便適時選擇恰當的算法。換言之,策略模式只適用於客戶端知道所有的算法或行爲的情況。
-
策略模式將造成系統產生很多具體策略類,任何細小的變化都將導致系統要增加一個新的具體策略類。
-
無法同時在客戶端使用多個策略類,也就是說,在使用策略模式時,客戶端每次只能使用一個策略類,不支持使用一個策略類完成部分功能後再使用另一個策略類來完成剩餘功能的情況。