設計模式之 - 策略模式(Strategy Pattern)

引入:項目中涉及到工做流,固然這個工做流的實現是由用戶根據不一樣的策略或者說方式傳入處理這個事件的人的審批鏈,後臺在存儲過程當中進行解析,而後生成最終的審批鏈,在系統中流轉進行審批。 好比審批鏈: 張三 -> 李四 -> 王五算法

因爲不少外部系統接入,因此係統提供多種審批鏈的生成方式供外部系統選擇,好比 1. 已經定好的好審批鏈的(叫作模板)傳入模板 ID 系統就能夠根據傳入的模板生成審批鏈; 2. 外部系統自定義審批鏈,則 外部系統直接傳入審批  鏈,張三 -> 李四 -> 王五 ,咱們系統進行解析存儲。數據庫

最近坐在旁邊的一哥們作這一塊,因而乎這幾天耳邊老是「策略」二字。由於當時不瞭解策略模式,以爲頗有趣,那麼多處理方式如何能調用到目標類進行處理,因此昨晚1點多睡不着,決定來學習下這個設計模式- 策略模式。 設計模式

書中定義: 定義一系列的算法,將每個算法封裝起來,並讓它們能夠互相替換。策略模式讓算法獨立於使用它的客戶而變化,是一種對象的行爲模式。下面以排序算法來學習下策略模式。ide

如圖是網上找到的一段資料:學習

排序算法配合策略模式代碼實現

1. 策略模式通常包括一個環境類即爲使用算法的角色,它在解決問題的時候採用多種策略。在其中維護一個抽象策略的引用實例,用於定義採用的所採用的策略,下文中定義類名爲 Context。 測試

2. 抽象類或者接口,爲所支持的算法聲明抽象方法,是全部策略類的父類 ,咱們使用Sort。this

3. 具體的策略類,實現了上面的接口或者繼承抽象類,實現其定義的抽象算法,在運行時具體類中的方法覆蓋實現的抽象方法來完成某個業務處理。spa

(1) 環境類代碼設計

package cn.aries.pattern.StrategyPattern;

public class Context {

    private Sort sortStrategy;

    public Context(Sort sortStrategy) {
        this.sortStrategy = sortStrategy;
    }
    
    public int[] sort(int[] arr){
        return sortStrategy.sort(arr);
    }
}

(2) 策略接口代碼code

package cn.aries.pattern.StrategyPattern;

public interface Sort {
    public int[] sort(int[] arr);
}

(3) 排序算法代碼

 a. 選擇排序

package cn.aries.pattern.StrategyPattern;

public class SelectionSort implements Sort {
    /**
     * 選擇排序
     */
    @Override
    public int[] sort(int[] arr) {
        int len = arr.length;
        int temp;

        for (int i = 0; i < len; i++) {
            temp = arr[i];
            int index = i;
            for (int j = i + 1; j < len; j++) {
                if (arr[j] < temp) {
                    temp = arr[j];
                    index = j;
                }
            }
            arr[index] = arr[i];
            arr[i] = temp;
        }
        System.out.println("this is selection sort !");
        return arr;
    }
}

b. 冒泡排序

package cn.aries.pattern.StrategyPattern;

public class BubbleSort implements Sort{

    /**
     * 冒泡排序
     */
    @Override
    public int[] sort(int[] arr) {
        int len = arr.length;
        for (int i = 0; i < len; i++) {
            for (int j = i+1; j < len; j++) {
                int temp;
                if(arr[i] > arr[j]){
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        System.out.println("this is bubble sort !");
        return arr;
    }
}

c. 插入排序

package cn.aries.pattern.StrategyPattern;

public class InsertionSort implements Sort {

    /**
     * 插入排序法
     */
    @Override
    public int[] sort(int[] arr) {
        int len = arr.length;

        for (int i = 1; i < len; i++) {
            int temp = arr[i];
            int j;
            for (j = i; j > 0; j--) {
                if (arr[j - 1] > temp) {
                    arr[j] = arr[j - 1];
                } else {
                    break;
                }
            }
            arr[j] = temp;
        }
        System.out.println("this is insertion sort !");
        return arr;
    }
}

(4) 測試代碼

package cn.aries.pattern.StrategyPattern;

public class App {
    public static void main(String[] args) {
        int[] arr = {8,4,5,2,62,2};
     //具體的這個策略類調用能夠在配置文件中設定,這裏建立不一樣的排序算法實例就會調用的不一樣策略的排序算法 Sort sortStrategy
= new SelectionSort(); Content content = new Content(sortStrategy); printArray(content.sort(arr)); } public static void printArray(int[] arr){ for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + ","); } } }

以上代碼就是使用策略模式實現不一樣排序方法的調用。若是引入新的排序算法,對系統無任何影響,之須要添加一個新的具體策略類,在該策略類中封裝新的算法,而後修改對應的配置文件應用該策略便可。

分析策略模式的優缺點

優勢:

  1. 提供了對「開閉原則」 的完美支持,在不修改原代碼的基礎上,靈活的新增算法或者行爲。

  2. 其定義了一個算法或者行爲族,能夠將公用的代碼提取到繼承的父類中,從了避免了重複的代碼。

  3. 其將每一個算法或者行爲封裝爲一個類,就是一個類只作一間事情,符合「單一職責」原則。

  4. 能夠避免使用多重條件轉換語句if(){}else{},將選擇使用什麼算法的行爲邏輯和算法分開,更易於維護。

缺點:

  客戶端必須知道全部的策略類,並自行的決定選擇使用哪個策略類。客戶端必須理解這些算法的區別,以便使用的使用選擇恰當的算法類,就是策略模式只適用於客戶端知道全部的算法和行爲的狀況。

回到開始項目中策略模式的運用

1. 每個外部系統接入的時候,已經定義好了使用什麼策略,而後將對應的策略寫入數據庫。

2. 每個策略類都配置在了xml文件中。

3. 當外部系統提交數據過來的時候,根據外部系統名稱到數據庫中查找當時接入系統時選擇的策略名稱 strategyName 。

4. 在要調用策略的位置使用上下午容器ac.getBean("strategyName");獲取到具體的策略類,就能夠根據客戶需求使用目標算法或者方式完成業務流程,相似以下代碼:

    

其實最終的結論,在使用策略的時候,一個業務可能有多中執行路徑或者執行方式供選擇(也就是多個策略),可是具體走那一條,仍是須要在調用的時候就間接的表示清楚,到此心中的謎團解開了。

相關文章
相關標籤/搜索