何为策略模式?
同一件事情,不同的类型,需要不同的策略去处理。就如书中所说的 “商场超市的促销方式”。 实际上,该功能如果用“简单工厂模式”也可以实现,不过有一些缺点。
比如:因为商场超市的促销方式比较多,打折的话,就有“88折、9折、5折”等等;返利的话,就有“满100返20,满300返80等等”;还有“无促销”等各种促销方式。
实际稍微分析一下,我们就发现上述所有的促销方式也就3大类,“打折/返利/正常”,我们完全可以将同种促销方式单独的封装起来,传各自需要的参数,重写父类的公共方法,即可。
所以策略模式相对来说,就是减少了“子类”,将同种类型的算法归为一类,提高了代码的重用型。
简而言之:“策略模式封装了不同的算法,同一种的类型的算法可以互相替换,并不影响使用该具体算法的客户”
”简单工厂模式与策略模式“:如果使用策略模式的话,我们的客户端的类就简洁许多,并且,耦合度也相对来说更小一些。与之相关的只有”CashContext“,并且具体的算法需要的子类也不在客户端显示,
如果仅仅是简单工厂的话,与之相关的有”CashSuper“、”CashFactory“两个类。
父类
1 public abstract class CashSuper { 2 public abstract double acceptMoney(double money); 3 }
三种促销方式的策略类
A--正常
public class CashNormal extends CashSuper { @Override public double acceptMoney(double money) { return money; } }
B--打折
public class CashReBate extends CashSuper { public double rate; public CashReBate(double rate){ this.rate = rate; } @Override public double acceptMoney(double money) { return money*rate; } }
C--返利
1 public class CashReturn extends CashSuper { 2 public double fullMoney; 3 public double returnMoney; 4 public CashReturn(double fullMoney, double returnMoney){ 5 this.fullMoney = fullMoney; 6 this.returnMoney = returnMoney; 7 } 8 @Override 9 public double acceptMoney(double money) { 10 double result = money; 11 if(money>=fullMoney){ 12 result = money - Math.floor(money/fullMoney)*returnMoney; 13 } 14 return result; 15 } 16 }
简单工厂与策略模式结合的类
1 public class CashContext { 2 /** 3 * 简单工厂与策略模式的结合使用, 4 * 这样,客户端只需要识别该类即可 5 */ 6 public CashSuper cashSuper = null; 7 public CashContext(String type){ 8 switch(type){ 9 case "正常": 10 cashSuper = new CashNormal(); 11 break; 12 case "打5折": 13 cashSuper = new CashReBate(0.5); 14 break; 15 case "满300返50": 16 cashSuper = new CashReturn(300,50); 17 break; 18 } 19 } 20 public double getResult(double money){ 21 return cashSuper.acceptMoney(money); 22 } 23 }
客户端的类
1 public class ResultClient { 2 public static void main(String[] args) { 3 Scanner scanner = new Scanner(System.in); 4 System.out.println("请输入消费金额:"); 5 double money = scanner.nextDouble(); 6 System.out.println("请输入促销方式之一:‘打5折’、‘正常’、‘满300返50’"); 7 String type = scanner.next(); 8 CashContext cashContext = new CashContext(type); 9 double result = cashContext.getResult(money); 10 System.out.println("最终需支付金额为:"+result); 11 } 12 }
引用书中的总结,即:”策略模式是一种计算一系列算法的方法,所有的算法完成的都是相同的工作,只是实现不同,他可以以相同的方式调用所有的算法,减少了各种算法与使用算法的耦合“;
”策略模式简化了单元测试,每个算法都有自己的类,可以单独测试“
不过,从以上的代码来看,我们会发现,有一些”僵硬“,确实是,比如:我要打5折,那我就要变CashContext里面的参数;这样的改动,如果对于变化频率比较高的事件来说的话,可能就会比较繁琐一些。因为你需要在CsashContext中的switch分支中不断的增加肯能出现的情况。