背景
接受到一个商场收银系统的续期,客户那边说需要做一个收银软件,根据客户所购买的单价和数量进行计算应该收多少钱。做完一版之后客户要求增加打折功能,然后还需要支持满减功能。
起初我的涉及思路是这样的,创建一个公共的接口根据type判断当前使用哪一种收款模式,然后选择对应的函数来计算所需要收的现金。
简单工厂模式
因为之前学习了简单工厂模式,觉得这种场景下也比较适用简单工厂模式,于是产生了以下的代码;先创建一个收费的父类。
publicabstractclassCashSuper{privateintnums;privatedoubleprice;protectedabstractdoubleacceptCash(doublemoney);}
然后分别定义普通收款模式、打折收款模式和满减模式三个类
classNormalCashextendsCashSuper{@OverrideprotecteddoubleacceptCash(doublemoney){returnmoney; }}classRebateCashextendsCashSuper{privatedoublerebate;publicRebateCash(doublerebate){this.rebate = rebate; }@OverrideprotecteddoubleacceptCash(doublemoney){returnmoney * rebate; }}classReturnCashextendsCashSuper{privatedoublemoneyCondition =0.0;privatedoublemoneyReturn =0.0;publicReturnCash(doublemoneyCondition,doublemoneyReturn){this.moneyCondition = moneyCondition;this.moneyReturn = moneyReturn; }@OverrideprotecteddoubleacceptCash(doublemoney){returnmoney - Math.floor(money / moneyCondition) * moneyReturn; }}
然后创建一个收款工厂就可以了
classCashFactory{publicstaticCashSupercreateAcceptCasg(inttype){ CashSuper cashSuper;switch(type) {case0: cashSuper =newNormalCash();break;case1: cashSuper =newRebateCash(0.7);// 打七折break;case2: cashSuper =newReturnCash(100,50);// 满100减50break;default: cashSuper =newNormalCash(); }returncashSuper; }}
这种模式下虽然也能解决这个需求,但是这个模式只是解决对象的创建问题,而且由于工厂本身也包括了所有的收费方式,商场是可能会经常性的更改打折额度和返利刻度,每次维护或者扩展都需要改动这个工厂,以致于代码需要重新编译部署,这真的是一种很糟糕的处理方式,所以它不是好的办法。
策略模式
面对算法的经常性的变动,应该使用策略模式。
** 策略模式 定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响使用时u案发的客户**
代码如下:客户端只需要调用这段代码即可完成,但是需要通过客户端判断使用哪个算法
classCashContexts{privateCashSuper cashSuper;publicCashContexts(CashSuper cashSuper){this.cashSuper = cashSuper; }publicdoublegetReesult(doublemoney){returncashSuper.acceptCash(money); }}
客户端:
publicstaticvoidmain(String[] args){ CashContexts cashContexts;doublemoney =100;inttype =0;switch(type) {case0: cashContexts =newCashContexts(newNormalCash());break;case1: cashContexts =newCashContexts(newRebateCash(0.7));break;case2: cashContexts =newCashContexts(newReturnCash(100,50));break;default: cashContexts =newCashContexts(newNormalCash());; }doublereesult = cashContexts.getReesult(money); System.out.println(reesult); }
策略模式与简单工厂模式结合
classCashContextt{privateCashSuper cashSuper;publicCashContextt(Integer type){switch(type) {case0: cashSuper =newNormalCash();break;case1: cashSuper =newRebateCash(0.7);break;case2: cashSuper =newReturnCash(100,50);break;default: cashSuper =newNormalCash(); } }publicdoublegetResult(doublemoney){returncashSuper.acceptCash(money); }}
回头想一想,其实策略模式是一种定义一系列算法的方法,从概念上来看,这些方法完成的都是相同的工作,只是实现不一样,它可以额用相同的方法调用所有的算法,减少了各种算法类与实用类之间的耦合