策略模式 Strategy
與策略相關的常見詞彙有:營銷策略、折扣策略、教學策略、記憶策略、學習策略....
「策略」意味着分狀況討論,而不是一律而論
面對不一樣年齡段的人,面對不一樣的商品,必然將會有不一樣的話術;
面對購物總價的範圍,極可能會有不一樣的折扣方案;
面對理解能力不一樣的學生,必然有不一樣的教學策略;
而在咱們程序的世界裏,「策略」就是分狀況討論。也就是
相似狀態模式中的條件分支或者選擇分支。
只不過
狀態模式中是事物的不一樣狀態,而策略模式中關注的是處理方法。
好比
if(totalPrice > 1000){
//9折
else if(totalPrice > 2000){
//8折
}else if(totalPrice > 3000){
//7折
}
這就是一種打折策略,對應於購物總金額的不一樣,採用不一樣的處理方法。
顯然,使用條件分支或者選擇語句,相似狀態模式中的分析,也存在相似的問題
若是條件過多,會致使
處理邏輯複雜
並且,策略的邏輯與業務邏輯
耦合在一塊兒,若是處理方法變化還須要修改業務邏輯方法,
擴展性差
並且,也
不適合增長新的策略方案
意圖
定義一系列的算法,把他們一個個的封裝起來,並使他們能夠互相轉換,本模式使得算法能夠獨立於使用它的客戶端而變化。
別名:政策Policy
策略模式與狀態模式本質同樣,只不過一個是狀態,一個是行爲算法。
結構
抽象策略角色Strategy
定義了抽象的策略,好比打折,排序等
定義了策略的一致性訪問接口,好比定義了一個排序接口 sort()
具體策略角色ConcreteStrategy
實現抽象策略的定義的接口,實現本身的行爲算法,好比ConcreteStrategyA冒泡 ConcreteStrategyB快排
環境類Context
維護Strategy,持有一個Strategy的引用,用來管理Strategy,能夠切換策略
是Strategy的使用者
代碼示例
排序接口,定義了一個sort方法
package strategy;
public interface SortStrategy {
void sort();
}
package strategy;
public class Bubble implements SortStrategy {
@Override
public void sort() {
System.out.println("冒泡排序,輸出結果...");
}
}
package strategy;
public class QuickSort implements SortStrategy {
@Override
public void sort() {
System.out.println("快速排序,輸出結果...");
}
}
環境類
內部持有一個SortStrategy,簡單起見初始化爲Bubble
使用一個簡單的方法進行切換
而且提供sort方法,代理strategy的sort方法
package strategy;
public class Context {
private SortStrategy strategy = new Bubble();
public void setStrategy(String strategy) {
if(strategy.equals("bubble")){
this.strategy = new Bubble();
}else if(strategy.equals("quick")){
this.strategy = new QuickSort();
}
}
public void sort() {
strategy.sort();
}
}
測試方法
package strategy;
public class Test {
public static void main(String[] args) {
Context context = new Context();
context.sort();
context.setStrategy("quick");
context.sort();
context.setStrategy("bubble");
context.sort();
}
}
上面的代碼能夠看得出來,具體的算法行爲,被封裝在了具體的策略類中,好比Bubble和QuickSort
經過環境類Context對算法進行管理切換。
總結
策略模式與狀態模式是相似的,藉助於多態的特性,以達到不一樣狀態不一樣行爲
不一樣的場景使用不一樣的算法,這本就是一種「不一樣狀態,不一樣行爲」的含義延伸
都是藉助於多態特性,進而也就是依賴倒置原則---面向抽象編程,其根本也是爲了「低耦合」。
策略模式中使用獨立的類來封裝不一樣的算法行爲,每個類封裝具體的行爲
策略模式主要是將
算法的定義與使用進行分開,算法被封裝在不一樣的策略類中
藉助於算法的環境類Context,針對抽象策略進行編程,符合依賴倒置原則
並且,新增長具體的算法,只須要增長一個新的具體的策略類便可。
策略模式將算法的定義與使用分開,具體的策略徹底能夠經過配置文件等方式注入到Context中,客戶端徹底不須要關注具體的策略
並且,
運行時能夠隨時的更換策略
策略模式的Context,咱們的示例中一個Context一個當前策略,那麼Context到底內部維護幾個策略?到底誰負責切換,是客戶端仍是Context
我的認爲都是靈活的,策略模式的核心就在於算法的定義與使用的解耦,在接下來的其餘事情,本身看狀況隨便來(隨便的前提是合理有效)
只要是涉及到
多種算法行爲的
切換:策略能夠運行時切換
複用:算法與使用解耦,算法能夠單獨擴展
封裝:屏蔽使用者對算法內部數據結構等邏輯的瞭解,不然若是算法的實現耦合在客戶端,客戶端不是一清二楚麼
都
能夠考慮策略模式,策略模式可以靈活的切換算法,以及算法獨立發展,符合開閉原則
可是相似狀態模式,策略模式也會產生不少小的具體的策略類,增長類的個數和運行時對象的個數。