設(shè)計模式—策略模式

本博客同步發(fā)表在http://hjxandhmr.github.io/2016/06/10/DesignPattern-Strategy/

今天我們來學習一種行為型模式,策略模式(Observer Pattern)。

模式定義

定義一系列算法,將每一個算法封裝起來,并讓它們可以相互替換。策略模式讓算法獨立于使用它的客戶而變化,也稱為政策模式(Policy)。

模式結(jié)構(gòu)

策略模式包含如下角色:

**Context: ** 環(huán)境類
**Strategy: ** 抽象策略類
**ConcreteStrategy: ** 具體策略類

UML圖

代碼實現(xiàn)

通常如果一個問題有多個解決方案或者稍有區(qū)別的操作時,最簡單的方式就是利用if-else or switch-case方式來解決,對于簡單的解決方案這樣做無疑是比較簡單、方便、快捷的,但是如果解決方案中包括大量的處理邏輯需要封裝,或者處理方式變動較大的時候則就顯得混亂、復(fù)雜,而策略模式則很好的解決了這樣的問題,它將各種方案分離開來,讓操作者根據(jù)具體的需求來動態(tài)的選擇不同的策略方案。 這里以簡單的計算操作(+、-、*、/)作為示例:

UML圖

Strategy.java

/**
 * 計算操作的抽象
 */
public interface Strategy {
    double calc(double paramA, double paramB);
}

AddStrategy.java


/**
 * 加法的具體實現(xiàn)策略
 */
public class AddStrategy implements Strategy {

    @Override
    public double calc(double paramA, double paramB) {
        System.out.println("Execute AddStrategy");
        return paramA + paramB;
    }
}

SubStrategy.java

/**
 * 減法的具體實現(xiàn)策略
 */
public class SubStrategy implements Strategy {
    @Override
    public double calc(double paramA, double paramB) {
        System.out.println("Execute SubStrategy");
        return paramA - paramB;
    }
}

MultiStrategy.java


/**
 * 乘法的具體實現(xiàn)策略
 */
public class MultiStrategy implements Strategy {
    @Override
    public double calc(double paramA, double paramB) {
        System.out.println("Execute MultiStrategy");
        return paramA * paramB;
    }
}

DivStrategy.java


/**
 * 除法的具體實現(xiàn)策略
 */
public class DivStrategy implements Strategy {
    @Override
    public double calc(double paramA, double paramB) {
        System.out.println("Execute DivStrategy");
        if (paramB == 0) {
            throw new IllegalArgumentException("Cannot divide into 0");
        }
        return paramA / paramB;
    }
}

Calc.java


/**
 * 進行計算操作的上下文環(huán)境
 */
public class Calc {

    private Strategy mStrategy;

    public void setStrategy(Strategy strategy) {
        this.mStrategy = strategy;
    }

    public double calc(double paramA, double paramB) {
        if (mStrategy == null) {
            throw new IllegalStateException("You haven't set the strategy for computing.");
        }
        return mStrategy.calc(paramA, paramB);
    }
}

測試類

public class MyClass {

    public double calc(Strategy strategy, double paramA, double paramB) {
        Calc calc = new Calc();
        calc.setStrategy(strategy);
        return calc.calc(paramA, paramB);
    }

    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        System.out.println("Calculation Add  " + myClass.calc(new AddStrategy(), 10, 5));
        System.out.println("Calculation Add  " + myClass.calc(new SubStrategy(), 10, 5));
        System.out.println("Calculation Add  " + myClass.calc(new MultiStrategy(), 10, 5));
        System.out.println("Calculation Add  " + myClass.calc(new DivStrategy(), 10, 5));
    }
}

運行結(jié)果

模式分析

  • 策略模式是一個比較容易理解和使用的設(shè)計模式,策略模式是對算法的封裝,它把算法的責任和算法本身分割開,委派給不同的對象管理。策略模式通常把一個系列的算法封裝到一系列的策略類里面,作為一個抽象策略類的子類。用一句話來說,就是“準備一組算法,并將每一個算法封裝起來,使得它們可以互換”。

  • 在策略模式中,應(yīng)當由客戶端自己決定在什么情況下使用什么具體策略角色。

  • 策略模式僅僅封裝算法,提供新算法插入到已有系統(tǒng)中,以及老算法從系統(tǒng)中“退休”的方便,策略模式并不決定在何時使用何種算法,算法的選擇由客戶端來決定。這在一定程度上提高了系統(tǒng)的靈活性,但是客戶端需要理解所有具體策略類之間的區(qū)別,以便選擇合適的算法,這也是策略模式的缺點之一,在一定程度上增加了客戶端的使用難度。

策略模式的優(yōu)點

  • 策略模式提供了對“開閉原則”的完美支持,用戶可以在不修改原有系統(tǒng)的基礎(chǔ)上選擇算法或行為,也可以靈活地增加新的算法或行為。

  • 策略模式提供了管理相關(guān)的算法族的辦法。

  • 策略模式提供了可以替換繼承關(guān)系的辦法。

  • 使用策略模式可以避免使用多重條件轉(zhuǎn)移語句。

策略模式的缺點

  • 客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。

  • 策略模式將造成產(chǎn)生很多策略類。

參考
http://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/strategy.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容