淺談Strategy策略模式

1、前言java

什麼是策略模式?算法

策略這個詞應該怎麼理解呢,打個比方說,咱們出門的時候選擇不一樣的出行方式,好比步行、騎自行車、坐公交、坐火車、坐飛機、坐火箭等等,這些出行方式,每一種都是一個策略。設計模式

再好比咱們去逛商場,商場如今正在搞活動,有打折的、滿減的、返利的等等,其實無論商場如何進行促銷,說到底都是一些算法,這些算法自己就是一種策略,而且這些算法是隨時可能互相替換的,好比針對同一件商品,今天打八折、明天滿100減30,這些策略間是能夠互換的。ide

策略模式(Strategy),定義了一組算法,將每一個算法都封裝起來,而且使它們之間能夠互換。佈局

2、策略模式的應用學習

一、什麼時候使用this

對於業務開發來講,業務邏輯的複雜是必然的,隨着業務發展,需求只會愈來愈複雜,爲了考慮到各類各樣的狀況,代碼中不可避免的會出現不少if-else。spa

一旦代碼中if-else過多,就會大大的影響其可讀性和可維護性,並且代碼顯得很low。.net

策略模式完美的解決了ifelse的煩惱!設計

二、方法

將這些算法封裝成一個一個的類,任意的替換

三、優勢

  • 算法能夠自由切換
  • 避免使用多重條件判斷
  • 擴展性良好,增長一個策略只需實現接口便可

四、缺點

  • 策略類數量會增多,每一個策略都是一個類,複用性很小
  • 全部的策略類都須要對外暴露

五、應用實例

  • 出行方式,自行車、汽車等,每一種出行方式都是一個策略
  • 商場促銷方式,打折、滿減等
  • java AWT中 LayoutManager ,即佈局管理器

六、注意事項

若是一個系統的策略多於四個,就須要考慮使用混合模式解決策略類膨脹的問題

640?wx_fmt=jpeg

3、策略模式的實現

下面就以商場促銷爲例使用策略模式實現商場促銷算法。UML圖以下:

一、上下文類

首先聲明一個 CashSuper 對象,經過構造方法,傳入具體的收費策略, getResult() 方法的功能爲根據收費策略的不一樣獲取計算結果。

package designMode.strategy;

public class CashContext {
    private CashSuper cashSuper;

    public CashContext(CashSuper cashSuper) {
        this.cashSuper = cashSuper;
    }

    public double getResult(double money){
        return cashSuper.acceptCash(money);
    }
}

二、現金收費抽象類

策略類,爲抽象類,抽象出收費的方法供子類實現。

package designMode.strategy;

public abstract class CashSuper {
    public abstract double acceptCash(double money);
}

三、正常收費子類

package designMode.strategy;

public class CashNormal extends CashSuper {
    @Override
    public double acceptCash(double money) {
        return money;
    }
}

四、打折收費子類

package designMode.strategy;

public class CashRebate extends CashSuper {
    private double moneyRebate = 0.8;

    public CashRebate(double moneyRebate) {
        this.moneyRebate = moneyRebate;
    }

    @Override
    public double acceptCash(double money) {
        return money*moneyRebate;
    }
}

五、返利收費子類

package designMode.strategy;

public class CashReturn extends  CashSuper {
    private double moneyConditation = 0.0;
    private double moneyReturn = 0.0d;

    public CashReturn(double moneyConditation, double moneyReturn) {
        this.moneyConditation = moneyConditation;
        this.moneyReturn = moneyReturn;
    }

    @Override
    public double acceptCash(double money) {
        double result = money;
        if(money>moneyConditation){
            result = money-Math.floor(money/moneyConditation)*moneyReturn;
        }
        return result;
    }
}

六、client客戶端

package designMode.strategy;

import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        CashContext cashContext = null;
        Scanner scanner = new Scanner(System.in);
        System.out.println("請輸入打折方式(1/2/3):");
        int in = scanner.nextInt();
        String type = "";
        switch (in){
            case 1:
                cashContext = new CashContext(new CashNormal());
                type += "正常收費";
                break;
            case 2:
                cashContext = new CashContext(new CashReturn(300,100));
                type +="滿300返100";
                break;
            case 3:
                cashContext = new CashContext(new CashRebate(0.8));
                type += "打八折";
                break;
            default:
                System.out.println("請輸入1/2/3");
                break;
        }
        double totalPrices = 0;
        System.out.print("請輸入單價:");
        double price = scanner.nextDouble();
        System.out.println("請輸入數量:");
        double num = scanner.nextDouble();
        totalPrices = cashContext.getResult(price * num);
        System.out.println("單價:" + price + ",數量:" + num + ",類型:" + type + ",合計:" + totalPrices);
        scanner.close();
    }
}

七、運行結果

4、策略模式與工程模式的區別

一、策略模式是行爲性模式,適應行爲的變化 ,強調父類的調用子類的特性

工廠模式是建立型模式,適應對象的變化,強調統一接口

二、策略模式封裝行爲,調用的時候必須先制定實例化具體的類,再調用抽象的方法; 策略模式的做用是讓一個對象在許多行爲中選擇一種行爲。

工廠模式封裝對象,實例化對象後調用的時候要知道具體的方法。

三、策略模式是調用不一樣類方法, 工廠模式是對父類進行重寫。

這倆個模式原本就是解決相似的問題,能夠說是孿生兄弟,且內部實現都差很少,都是經過子類來覆蓋父類而已,不過簡單工廠是把父類直接擺在客戶端,而策略模式是將父類隱藏在Context裏面,這樣封裝更好。

四、舉個例子
(1)產品之於加減乘除,水果之於蘋果梨橘子香蕉,文具之於筆尺刀,這時產品比較具體、有限和沒有多個算法重疊,這時實用簡單工廠模式。
(2)產品之於商場促銷中的返利(可爲300返100、500返200、10000返500等等無數)、折扣(2折、2.5折、6折、9折、9.1折等等無數)、正常購買、消費積分(100元10積分、200元30積分等等無數),這時產品構造又屢次重疊,且有在不一樣時刻應用不一樣的規則時使用策略模式。

五、總結

簡單工廠模式只是解決了對象的建立問題,工廠須要包括全部的產品對象的建立,若是產品對象形式常常變化,就須要常常改動工廠,以至代碼從新編譯。因此策略模式就誕生了,策略模式---它定義了算法家族,分別封裝起來,而不是像簡單產品模式同樣定義全部的產品類,讓他們之間能夠互相替換,此模式讓算法的變化,不會影響到使用算法的客戶,使客戶擁有相同的訪問過程。
簡單工廠模式的核心是「簡單工廠模式就是用來封裝全部的產品對象的」。

策略模式理解核心是「策略模式就是用來封裝算法的,但在實踐中,咱們發現能夠用它來封裝幾乎任何類型的規則,只要在分析過程當中遇到須要在不一樣時間應用不一樣的業務規則,就能夠考慮使用策略模式處理這種變化的可能性」。

在基本的策略模式中,選擇所用的具體實現的算法的職責由客戶端對象承擔,並轉給策略模式的Context對象。這是策略模式自己純粹的定義,因此,「選擇所用最終怎樣處理」還有不少文章可作。
看了課本以後對於這兩個模式仍是有不少不理解的地方,可是相信隨着對設計模式進一步的學習,可以更好地體會到這其中的奧妙,學習是一個按部就班的過程。

 

推薦博客

素小暖講設計模式

相關文章
相關標籤/搜索