设计模式18---设计模式之策略模式(Strategy)(行为型)
1.場景模擬
簡單的報(bào)價(jià)管理系統(tǒng):
對于普通用戶和新用戶報(bào)全價(jià)
對于老客戶統(tǒng)一折扣5%
對于大客戶統(tǒng)一折扣10%
2.不用模式的解決方案
package demo16.strategy.example2; /*** 價(jià)格管理,主要完成計(jì)算向客戶所報(bào)價(jià)格的功能*/ public class Price {/*** 報(bào)價(jià),對不同類型的,計(jì)算不同的價(jià)格* @param goodsPrice 商品銷售原價(jià)* @param customerType 客戶類型* @return 計(jì)算出來的,應(yīng)該給客戶報(bào)的價(jià)格*/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); }//其余人員都是報(bào)原價(jià)return goodsPrice;}/*** 為新客戶或者是普通客戶計(jì)算應(yīng)報(bào)的價(jià)格* @param goodsPrice 商品銷售原價(jià)* @return 計(jì)算出來的,應(yīng)該給客戶報(bào)的價(jià)格*/private double calcPriceForNormal(double goodsPrice){System.out.println("對于新客戶或者是普通客戶,沒有折扣");return goodsPrice;}/*** 為老客戶計(jì)算應(yīng)報(bào)的價(jià)格* @param goodsPrice 商品銷售原價(jià)* @return 計(jì)算出來的,應(yīng)該給客戶報(bào)的價(jià)格*/private double calcPriceForOld(double goodsPrice){System.out.println("對于老客戶,統(tǒng)一折扣5%");return goodsPrice*(1-0.05);}/*** 為大客戶計(jì)算應(yīng)報(bào)的價(jià)格* @param goodsPrice 商品銷售原價(jià)* @return 計(jì)算出來的,應(yīng)該給客戶報(bào)的價(jià)格*/private double calcPriceForLarge(double goodsPrice){System.out.println("對于大客戶,統(tǒng)一折扣10%");return goodsPrice*(1-0.1); } }3.有何問題?
會經(jīng)常有這樣的需要,在公司周年慶的時(shí)候,所有的客戶額外增加3%的折扣,在換季的時(shí)候普通用戶額外增加3%的折扣,然后過了促銷時(shí)間,價(jià)格又要漲回來,那么這個(gè)價(jià)格類將會非常的龐大,而且,方法非常的多。
看到這,朋友們很快就想到:如何實(shí)現(xiàn)才能讓價(jià)格類中的計(jì)算報(bào)價(jià)的算法,很容易的實(shí)現(xiàn)可維護(hù),可擴(kuò)展,而且可以動態(tài)的切換變化呢?
4.使用策略模式來解決問題
4.1策略模式定義
定義一系列的算法,把他們一個(gè)個(gè)封裝起來,并且可以使他們相互替換,本模式使得算法可獨(dú)立于使用它的客戶而變化。
4.2策略模式的結(jié)構(gòu)圖
?
4.3策略模式示例代碼
package demo16.strategy.example3;/*** 策略,定義算法的接口*/ public interface Strategy {/*** 某個(gè)算法的接口,可以有傳入?yún)?shù),也可以有返回值*/public void algorithmInterface(); } ********************************************************************* package demo16.strategy.example3;/*** 實(shí)現(xiàn)具體的算法*/ public class ConcreteStrategyA implements Strategy {public void algorithmInterface() {//具體的算法實(shí)現(xiàn) }} ********************************************************************* package demo16.strategy.example3;/*** 實(shí)現(xiàn)具體的算法*/ public class ConcreteStrategyB implements Strategy {public void algorithmInterface() {//具體的算法實(shí)現(xiàn) }}package demo16.strategy.example3;/*** 實(shí)現(xiàn)具體的算法*/ public class ConcreteStrategyC implements Strategy {public void algorithmInterface() {//具體的算法實(shí)現(xiàn) } } ********************************************************************* package demo16.strategy.example3;/*** 上下文對象,通常會持有一個(gè)具體的策略對象*/ public class Context {/*** 持有一個(gè)具體的策略對象*/private Strategy strategy;/*** 構(gòu)造方法,傳入一個(gè)具體的策略對象* @param aStrategy 具體的策略對象*/public Context(Strategy aStrategy) {this.strategy = aStrategy;}/*** 上下文對客戶端提供的操作接口,可以有參數(shù)和返回值*/public void contextInterface() {//通常會轉(zhuǎn)調(diào)具體的策略對象進(jìn)行算法運(yùn)算strategy.algorithmInterface();} }5.使用策略模式重寫實(shí)例
package demo16.strategy.example4;/*** 策略,定義計(jì)算報(bào)價(jià)算法的接口*/ public interface Strategy {/*** 計(jì)算應(yīng)報(bào)的價(jià)格* @param goodsPrice 商品銷售原價(jià)* @return 計(jì)算出來的,應(yīng)該給客戶報(bào)的價(jià)格*/public double calcPrice(double goodsPrice); } ************************************************************************ package demo16.strategy.example4; /*** 具體算法實(shí)現(xiàn),為新客戶或者是普通客戶計(jì)算應(yīng)報(bào)的價(jià)格*/ public class NormalCustomerStrategy implements Strategy{public double calcPrice(double goodsPrice) {System.out.println("對于新客戶或者是普通客戶,沒有折扣");return goodsPrice;} } *********************************************************************** package demo16.strategy.example4; /*** 具體算法實(shí)現(xiàn),為老客戶計(jì)算應(yīng)報(bào)的價(jià)格*/ public class OldCustomerStrategy implements Strategy{public double calcPrice(double goodsPrice) {System.out.println("對于老客戶,統(tǒng)一折扣5%");return goodsPrice*(1-0.05);} } *********************************************************************** package demo16.strategy.example4; /*** 具體算法實(shí)現(xiàn),為大客戶計(jì)算應(yīng)報(bào)的價(jià)格*/ public class LargeCustomerStrategy implements Strategy{public double calcPrice(double goodsPrice) {System.out.println("對于大客戶,統(tǒng)一折扣10%");return goodsPrice*(1-0.1);} } *********************************************************************** package demo16.strategy.example4; /*** 價(jià)格管理,主要完成計(jì)算向客戶所報(bào)價(jià)格的功能*/ public class Price {/*** 持有一個(gè)具體的策略對象*/private Strategy strategy = null;/*** 構(gòu)造方法,傳入一個(gè)具體的策略對象* @param aStrategy 具體的策略對象*/public Price(Strategy aStrategy){this.strategy = aStrategy;} /*** 報(bào)價(jià),計(jì)算對客戶的報(bào)價(jià)* @param goodsPrice 商品銷售原價(jià)* @return 計(jì)算出來的,應(yīng)該給客戶報(bào)的價(jià)格*/public double quote(double goodsPrice){return this.strategy.calcPrice(goodsPrice);} } *********************************************************************** package demo16.strategy.example4;public class Client {public static void main(String[] args) {//1:選擇并創(chuàng)建需要使用的策略對象Strategy strategy = new LargeCustomerStrategy();//2:創(chuàng)建上下文Price ctx = new Price(strategy);//3:計(jì)算報(bào)價(jià)double quote = ctx.quote(1000);System.out.println("向客戶報(bào)價(jià):"+quote);} }6.模式講解
6.1要點(diǎn)
功能:把具體的算法從具體的業(yè)務(wù)處理中獨(dú)立出來,把他們實(shí)現(xiàn)成為單獨(dú)的算法類,從而形成一系列的算法,并讓這些算法可以相互替換。
策略算法是相同行為的不同實(shí)現(xiàn)
什么時(shí)候選用:多個(gè)if-else語句的時(shí)候就可以選用
6.2策略模式的調(diào)用順序示意圖
首先客戶端選擇并創(chuàng)建具體的策略對象
其次創(chuàng)建上下文
最后調(diào)用上下文的方法來執(zhí)行功能了
?
6.3當(dāng)添加新的策略時(shí)候
只需要動下面代碼,是不是很簡單,很方便呢?
//1:選擇并創(chuàng)建需要使用的策略對象
Strategy strategy = new LargeCustomerStrategy();
6.4另一種策略模式調(diào)用示意圖
?
6.5策略模式優(yōu)缺點(diǎn)
優(yōu)點(diǎn):定義一系列算法,避免使用多重條件語句,更好的擴(kuò)展性
缺點(diǎn):客戶端必須了解每種策略的不同,增加了對象數(shù)目,只適合扁平的算法結(jié)構(gòu)(地位平等的算法)
6.6設(shè)計(jì)模式的本質(zhì)
分離算法,選擇實(shí)現(xiàn)
總結(jié)
以上是生活随笔為你收集整理的设计模式18---设计模式之策略模式(Strategy)(行为型)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EJB教程实例
- 下一篇: 设计模式16——Memento设计模式