1、前言java
什麼是策略模式?算法
策略這個詞應該怎麼理解呢,打個比方說,咱們出門的時候選擇不一樣的出行方式,好比步行、騎自行車、坐公交、坐火車、坐飛機、坐火箭等等,這些出行方式,每一種都是一個策略。設計模式
再好比咱們去逛商場,商場如今正在搞活動,有打折的、滿減的、返利的等等,其實無論商場如何進行促銷,說到底都是一些算法,這些算法自己就是一種策略,而且這些算法是隨時可能互相替換的,好比針對同一件商品,今天打八折、明天滿100減30,這些策略間是能夠互換的。ide
策略模式(Strategy),定義了一組算法,將每一個算法都封裝起來,而且使它們之間能夠互換。佈局
2、策略模式的應用學習
一、什麼時候使用this
對於業務開發來講,業務邏輯的複雜是必然的,隨着業務發展,需求只會愈來愈複雜,爲了考慮到各類各樣的狀況,代碼中不可避免的會出現不少if-else。spa
一旦代碼中if-else過多,就會大大的影響其可讀性和可維護性,並且代碼顯得很low。.net
策略模式完美的解決了ifelse的煩惱!設計
二、方法
將這些算法封裝成一個一個的類,任意的替換
三、優勢
四、缺點
五、應用實例
六、注意事項
若是一個系統的策略多於四個,就須要考慮使用混合模式解決策略類膨脹的問題
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對象。這是策略模式自己純粹的定義,因此,「選擇所用最終怎樣處理」還有不少文章可作。
看了課本以後對於這兩個模式仍是有不少不理解的地方,可是相信隨着對設計模式進一步的學習,可以更好地體會到這其中的奧妙,學習是一個按部就班的過程。
推薦博客