一、策略模式
在策略(Strategy Pattern)中,一個類的行為或算法可以在運行時動態(tài)的更改。這種類型的設計模式屬于行為模式(Behavioral Pattern-對象間通信)。
在策略模式中,我們創(chuàng)建表示各種策略的對象和一個行為隨著策略對象改變而改變的context對象。策略對象改變context對象的執(zhí)行算法。
二、介紹
意圖: 定義一系列算法,把它們一個個封裝起來,并且是她們可互相替換。
Define a family of algorithms, encapsulate each one, and make them interchangeable
主要解決: 在有多種算法相似的情況下,使用if...else 所帶來的復雜和難以維護。
何時使用: 一個系統(tǒng)中有許多許多類,而區(qū)分它們的只是它們直接的行為。
如何解決: 將這些算法封裝成一個一個類,任意替換。
關鍵代碼: 實現(xiàn)同一個接口。
應用實例:
- 諸葛亮的錦囊妙計,每個錦囊就是一個策略。
- 旅行的出游方式,選擇,??,,,,每一種旅行方式都是一個策略。
- Java AWT 中的LayoutManager。(這個不熟悉)
優(yōu)點:
- 算法可以自由的切換。
- 避免使用多重條件判斷。
- 擴展性良好。
缺點:
- 策略類會增多。
- 所有的策略類都需要對外暴露。
使用場景: - 如果在一個系統(tǒng)中有許多類,它們之間的區(qū)別僅在于它們的行為,那么使用策略模式可以動態(tài)地讓一個對象在許多行為中選擇一種行為。
- 一個系統(tǒng)需要動態(tài)地在幾種算法中選擇一種。
- 如果一個對象有許多行為,如果不用恰當?shù)哪J剑@些行為就只好使用多重的條件選擇語句來實現(xiàn)。
注意事項: 如果一個系統(tǒng)中的策略多于4個,就是需要考慮使用混合模式,解決策略模式膨脹的問題。
三、實現(xiàn)
類結構圖如下:

策略模式類圖.png
- Context角色:起承上啟下封裝作用,屏蔽高層模塊對策略、算法的直接訪問,封裝可能存在的變化。
- Strategy抽象策略角色:策略、算法家族的抽象,通常為接口,定義每個策略或算法必須具有的方法和屬性。
- ConcreteStrategy具體策略角色:實現(xiàn)抽象策略中的操作,該類含有具體的算法。
- 創(chuàng)建策略接口(Strategy):
public interface Strategy {
int doOperation(int operator1, int operator2);
}
- 創(chuàng)建策略具體算法實現(xiàn)類(OperationAdd、OperationMultiply、OperationSubstract):
public class OperationAdd implements Strategy {
@Override
public int doOperation(int operator1, int operator2) {
return operator1 + operator2;
}
}
- 創(chuàng)建Context類:
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int operator1, int operator2) {
return strategy.doOperation(operator1, operator2);
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
}
- 使用 Context 來查看當它改變策略 Strategy 時的行為變化。
public class Test {
public static void main(String[] args) {
int operator1 = 10;
int operator2 = 2;
int result = 0;
Context ctx = new Context(new OperationAdd());
result = ctx.executeStrategy(operator1, operator2);
System.out.println(operator1 + " + " + operator2 + " = " + result);
ctx.setStrategy(new OperationMultiply());
result = ctx.executeStrategy(operator1, operator2);
System.out.println(operator1 + " * " + operator2 + " = " + result);
ctx.setStrategy(new OperationSubstract());
result = ctx.executeStrategy(operator1, operator2);
System.out.println(operator1 + " - " + operator2 + " = " + result);
}
}
- 結果

輸出結果.png