设计模式(策略模式)

来源:互联网 发布:淘宝马切达工作室 编辑:程序博客网 时间:2024/05/18 00:45
本次的例子是一个商场收银软件。收银的算法其实很简单,就是把商品单价乘以数量,累加起来就是最后的金额。
    但是商场经常进行各种促销活动,如打折,满300减80等。正如上一个计算器的例子一样,一般人修改收银系统时,会用switch语句来判断此时的活动是什么,如:
switch(Type){case "打九折":    totalPrices = Qty*Price*0.9;    break;case "满300减80":    totalPrices = Qty*Price;    if(totalPrices>300)        totalPrice = totalPrices - 80;    break;}


大多人都会这么写。你觉得这样没问题,但是如果商场又加了打7折,打6折,满600减200等一大堆促销活动,难道有几个你就添加几个switch分支吗?
要解决这样的问题,首先我们可以上简单工厂模式来实现。
先抽象一个现金超类:
        public abstract class CashSuper {public abstract double acceptCash(double money);}再来一个正常收费的类,继承现金超类:public class CashNormal extends CashSuper {@Overridepublic double acceptCash(double money) {return money;}} 


打折的类:
        public class CashRebate extends CashSuper {private double moneyRebate = 1d;public CashRebate(String moneyRebate){this.moneyRebate = Double.parseDouble(moneyRebate);}@Overridepublic double acceptCash(double money) {return money*moneyRebate;}}


返利的类:
        public class CashReturn extends CashSuper {//返利条件private double moneyCondition = 0.0d;//返利金额private double moneyReturn = 0.0d;public CashReturn(String moneyCondition,String moneyReturn){this.moneyCondition = Double.parseDouble(moneyCondition);this.moneyReturn = Double.parseDouble(moneyReturn);}@Overridepublic double acceptCash(double money) {double result = money;if(money>=moneyCondition){//若金额大于返利条件,而总额为原金额减去返利金额result = money - moneyReturn;}return result;}}  


最后就是工厂类了:
        public class CashFactory {public static CashSuper createCashAccept(String type){CashSuper cs = null;switch(type){case "正常收费":cs = new CashNormal();break;case "满300减100":cs = new CashReturn("300","100");break;case "打8折":cs = new CashRebate("0.8");break;}return cs;}}


用工厂模式的好处就在于,打折只要输入打几折,返利只要输入返利条件和返利金额,这样就不用在switch中加入一大堆的分支了。
但是,商场可能经常性的更改促销方式,每次维护都要去改动工厂,以致于代码需要重新编译部署,所以这并不是最好的方法。
面对算法的时常变动,有更好的方法:
策略模式
策略模式需要些一个上下文类,用你的算法来配置它。比如现在写一个CashContext类
        public class CashContext {private CashSuper cs;public CashContext(CashSuper cSuper){this.cs = cSuper;}public double getResult(double money){return cs.acceptCash(money);}}


这里的CashSuper就是你的算法,继承这个算法的子类有CashReturn何CashRebate等,因此,客户端调用的时候这样写:
CashContext cc = null;switch(type){case "正常收费":cc = new CashContext(new CashNormal());break;case "满300减100":cc = new CashContext(new CashReturn("300","100"));break;case "打8折":cc = new CashContext(new CashRebate("0.8"));break;}totalPrices = cc.getResult(price * Qty);}


但是这样的话,为了让界面和逻辑业务彻底分离,我们尽量不要在客户端调用算法的时候使用判断,所以我们将策略模式和简单工厂模式结合起来。所以,上下文类应该改成这样:
        public class CashContext {private CashSuper cs = null;public CashContext(String type){switch(type){case "正常收费":cs = new CashNormal();break;case "满300减80":cs = new CashReturn("300","100");break;case "打8折":cs = new CashRebate("0.8");break;}}public double getResult(double money){return cs.acceptCash(money);}}


这样把判断的事情交给了上下文类,客户端调用的时候只要把促销的类型作为参数传递给它就可以了。
CashContext csuper = new CashContext("打8折");double totalPrices = 0d;totalPrices = csuper.getResult(Price*Qty);


 好吧,策略模式写完了。但是我个人认为这个东西有点难理解,我一直没搞懂工厂类和上下文类的作用差别在哪?有人能告诉我么。
0 0
原创粉丝点击