設計模式18—設計模式之策略模式(Strategy)(行為型)

來源:互聯網
上載者:User
1.情境類比

簡單的報價管理系統:
對於普通使用者和新使用者報全價
對於老客戶統一折扣5%
對於大客戶統一折扣10%
2.不用模式的解決方案

package demo16.strategy.example2;/** * 價格管理,主要完成計算向客戶所報價格的功能 */public class Price {/** * 報價,對不同類型的,計算不同的價格 * @param goodsPrice 商品銷售原價 * @param customerType 客戶類型 * @return 計算出來的,應該給客戶報的價格 */public double quote(double goodsPrice,String customerType){if("普通客戶".equals(customerType)){return this.calcPriceForNormal(goodsPrice);}else if("老客戶".equals(customerType)){return this.calcPriceForOld(goodsPrice);}else if("大客戶".equals(customerType)){return this.calcPriceForLarge(goodsPrice);}//其餘人員都是報原價return goodsPrice;}/** * 為新客戶或者是普通客戶計算應報的價格 * @param goodsPrice 商品銷售原價 * @return 計算出來的,應該給客戶報的價格 */private double calcPriceForNormal(double goodsPrice){System.out.println("對於新客戶或者是普通客戶,沒有折扣");return goodsPrice;}/** * 為老客戶計算應報的價格 * @param goodsPrice 商品銷售原價 * @return 計算出來的,應該給客戶報的價格 */private double calcPriceForOld(double goodsPrice){System.out.println("對於老客戶,統一折扣5%");return goodsPrice*(1-0.05);}/** * 為大客戶計算應報的價格 * @param goodsPrice 商品銷售原價 * @return 計算出來的,應該給客戶報的價格 */private double calcPriceForLarge(double goodsPrice){System.out.println("對於大客戶,統一折扣10%");return goodsPrice*(1-0.1);}}
3.有何問題?

會經常有這樣的需要,在公司周年慶的時候,所有的客戶額外增加3%的折扣,在換季的時候普通使用者額外增加3%的折扣,然後過了促銷時間,價格又要漲回來,那麼這個價格類將會非常的龐大,而且,方法非常的多。
看到這,朋友們很快就想到:如何?才能讓價格類中的計算報價的演算法,很容易的實現可維護,可擴充,而且可以動態切換變化呢?
4.使用原則模式來解決問題4.1策略模式定義

定義一系列的演算法,把他們一個個封裝起來,並且可以使他們相互替換,本模式使得演算法可獨立於使用它的客戶而變化。
4.2策略模式的結構圖

 
4.3策略模式範例程式碼

package demo16.strategy.example3;/** * 策略,定義演算法的介面 */public interface Strategy {/** * 某個演算法的介面,可以有傳入參數,也可以有傳回值 */public void algorithmInterface();}*********************************************************************package demo16.strategy.example3;/** * 實現具體的演算法 */public class ConcreteStrategyA implements Strategy {public void algorithmInterface() {//具體的演算法實現}}*********************************************************************package demo16.strategy.example3;/** * 實現具體的演算法 */public class ConcreteStrategyB implements Strategy {public void algorithmInterface() {//具體的演算法實現}}package demo16.strategy.example3;/** * 實現具體的演算法 */public class ConcreteStrategyC implements Strategy {public void algorithmInterface() {//具體的演算法實現}}*********************************************************************package demo16.strategy.example3;/** * 內容物件,通常會持有一個具體的策略對象 */public class Context {/** * 持有一個具體的策略對象 */private Strategy strategy;/** * 構造方法,傳入一個具體的策略對象 * @param aStrategy 具體的策略對象 */public Context(Strategy aStrategy) {this.strategy = aStrategy;}/** * 上下文對用戶端提供的操作介面,可以有參數和傳回值 */public void contextInterface() {//通常會轉調具體的策略對象進行演算法運算strategy.algorithmInterface();}}
5.使用原則模式重寫執行個體
package demo16.strategy.example4;/** * 策略,定義計算報價演算法的介面 */public interface Strategy {/** * 計算應報的價格 * @param goodsPrice 商品銷售原價 * @return 計算出來的,應該給客戶報的價格 */public double calcPrice(double goodsPrice);}************************************************************************package demo16.strategy.example4;/** * 具體演算法實現,為新客戶或者是普通客戶計算應報的價格 */public class NormalCustomerStrategy implements Strategy{public double calcPrice(double goodsPrice) {System.out.println("對於新客戶或者是普通客戶,沒有折扣");return goodsPrice;}}***********************************************************************package demo16.strategy.example4;/** * 具體演算法實現,為老客戶計算應報的價格 */public class OldCustomerStrategy implements Strategy{public double calcPrice(double goodsPrice) {System.out.println("對於老客戶,統一折扣5%");return goodsPrice*(1-0.05);}}***********************************************************************package demo16.strategy.example4;/** * 具體演算法實現,為大客戶計算應報的價格 */public class LargeCustomerStrategy implements Strategy{public double calcPrice(double goodsPrice) {System.out.println("對於大客戶,統一折扣10%");return goodsPrice*(1-0.1);}}***********************************************************************package demo16.strategy.example4;/** * 價格管理,主要完成計算向客戶所報價格的功能 */public class Price {/** * 持有一個具體的策略對象 */private Strategy strategy = null;/** * 構造方法,傳入一個具體的策略對象 * @param aStrategy 具體的策略對象 */public Price(Strategy aStrategy){this.strategy = aStrategy;}/** * 報價,計算對客戶的報價 * @param goodsPrice 商品銷售原價 * @return 計算出來的,應該給客戶報的價格 */public double quote(double goodsPrice){return this.strategy.calcPrice(goodsPrice);}}***********************************************************************package demo16.strategy.example4;public class Client {public static void main(String[] args) {//1:選擇並建立需要使用的策略對象Strategy strategy = new LargeCustomerStrategy();//2:建立上下文Price ctx = new Price(strategy);//3:計算報價double quote = ctx.quote(1000);System.out.println("向客戶報價:"+quote);}}
6.模式講解6.1要點

功能:把具體的演算法從具體的業務處理中獨立出來,把他們實現成為單獨的演算法類,從而形成一系列的演算法,並讓這些演算法可以相互替換。
策略演算法是相同行為的不同實現
什麼時候選用
:多個if-else語句的時候就可以選用
6.2策略模式的調用順序

首先用戶端選擇並建立具體的策略對象
其次建立上下文
最後調用內容相關的方法來執行功能了
 
6.3當添加新的策略時候

只需要動下面代碼,是不是很簡單,很方便呢?
//1:選擇並建立需要使用的策略對象
Strategy strategy = new LargeCustomerStrategy();
6.4另一種策略模式調用

 
6.5策略模式優缺點

優點:定義一系列演算法,避免使用多重條件陳述式,更好的擴充性
缺點:用戶端必須瞭解每種策略的不同,增加了對象數目,只適合扁平的演算法結構(地位平等的演算法)
6.6設計模式的本質

分離演算法,選擇實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.