策略模式 Strategy 政策Policy 行爲型 設計模式(二十五)

策略模式 Strategy
image_5c21cbb4_55b2
 
image_5c21cbb4_3b5
與策略相關的常見詞彙有:營銷策略、折扣策略、教學策略、記憶策略、學習策略....
「策略」意味着分狀況討論,而不是一律而論
面對不一樣年齡段的人,面對不一樣的商品,必然將會有不一樣的話術;
面對購物總價的範圍,極可能會有不一樣的折扣方案;
面對理解能力不一樣的學生,必然有不一樣的教學策略;
 
而在咱們程序的世界裏,「策略」就是分狀況討論。也就是 相似狀態模式中的條件分支或者選擇分支
只不過 狀態模式中是事物的不一樣狀態,而策略模式中關注的是處理方法
好比
if(totalPrice > 1000){
//9折
else if(totalPrice > 2000){
//8折
}else if(totalPrice > 3000){
//7折
}
這就是一種打折策略,對應於購物總金額的不一樣,採用不一樣的處理方法。
顯然,使用條件分支或者選擇語句,相似狀態模式中的分析,也存在相似的問題
若是條件過多,會致使 處理邏輯複雜
並且,策略的邏輯與業務邏輯 耦合在一塊兒,若是處理方法變化還須要修改業務邏輯方法, 擴展性差
並且,也 不適合增長新的策略方案

意圖

定義一系列的算法,把他們一個個的封裝起來,並使他們能夠互相轉換,本模式使得算法能夠獨立於使用它的客戶端而變化。
別名:政策Policy
策略模式與狀態模式本質同樣,只不過一個是狀態,一個是行爲算法。

結構

image_5c21cbb4_22ad
抽象策略角色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();
    }
}

 

image_5c21cbb4_406f
上面的代碼能夠看得出來,具體的算法行爲,被封裝在了具體的策略類中,好比Bubble和QuickSort
經過環境類Context對算法進行管理切換。

總結

策略模式與狀態模式是相似的,藉助於多態的特性,以達到不一樣狀態不一樣行爲
不一樣的場景使用不一樣的算法,這本就是一種「不一樣狀態,不一樣行爲」的含義延伸
都是藉助於多態特性,進而也就是依賴倒置原則---面向抽象編程,其根本也是爲了「低耦合」。
 
策略模式中使用獨立的類來封裝不一樣的算法行爲,每個類封裝具體的行爲
策略模式主要是將 算法的定義與使用進行分開,算法被封裝在不一樣的策略類中
藉助於算法的環境類Context,針對抽象策略進行編程,符合依賴倒置原則 
並且,新增長具體的算法,只須要增長一個新的具體的策略類便可。
 
策略模式將算法的定義與使用分開,具體的策略徹底能夠經過配置文件等方式注入到Context中,客戶端徹底不須要關注具體的策略
並且, 運行時能夠隨時的更換策略
 
策略模式的Context,咱們的示例中一個Context一個當前策略,那麼Context到底內部維護幾個策略?到底誰負責切換,是客戶端仍是Context
我的認爲都是靈活的,策略模式的核心就在於算法的定義與使用的解耦,在接下來的其餘事情,本身看狀況隨便來(隨便的前提是合理有效)
 
只要是涉及到 多種算法行爲
切換:策略能夠運行時切換
複用:算法與使用解耦,算法能夠單獨擴展
封裝:屏蔽使用者對算法內部數據結構等邏輯的瞭解,不然若是算法的實現耦合在客戶端,客戶端不是一清二楚麼
能夠考慮策略模式,策略模式可以靈活的切換算法,以及算法獨立發展,符合開閉原則 
 
可是相似狀態模式,策略模式也會產生不少小的具體的策略類,增長類的個數和運行時對象的個數。
相關文章
相關標籤/搜索