一、策略模式
1.策略模式是一种定义一系列算法的方法,所有算法完成的都是相同的工作,只是实现不同,策略模式可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。(简单一点,替换掉if/else/switch)
2.优点:
- 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。 -符合开闭原则,扩展性好,便于维护。避免使用多重条件判断
3.缺点:
- 策略如果很多,会造成策略类膨胀。使用者必须清楚所有的策略类及用途。
二、实例:商场收银软件
UML图:
package DHSJ_clms;
public abstract class CashSuper {
public abstract double acceptCash(double money);
}
package DHSJ_clms;
public class CashNormal extends CashSuper {
@Override
public double acceptCash(double money) {
return money;//原价
}
}
package DHSJ_clms;
public class CashRebate extends CashSuper {
private double moneyRebate;//折扣
public CashRebate(String moneyRebate) {
this.moneyRebate = Double.parseDouble(moneyRebate);
}
@Override
public double acceptCash(double money) {
return money*moneyRebate;
}
}
package DHSJ_clms;
public class CashReturn extends CashSuper {
private double moneyCondition;//满多少
private double moneyReturn;//减多少钱
//合起来就是满n钱时减m钱,如满300减100
public CashReturn(String moneyCondition, String moneyReturn) {
this.moneyCondition = Double.parseDouble(moneyCondition);
this.moneyReturn = Double.parseDouble(moneyReturn);
}
@Override
public double acceptCash(double money) {
double result=money;
if(money>=moneyCondition)
result=money-Math.floor(money/moneyCondition)*moneyReturn;
return result;//原价-返利值
}
}
注意:下面的CashContext可以有两种方法实现:
法1:策略模式
package DHSJ_clms;
public class CashContext {
private CashSuper cashsuper;
public CashContext(CashSuper cashsuper)
{
this.cashsuper=cashsuper;
}
public double GetResult(double money)
{
return cashsuper.acceptCash(money);
}
}
package DHSJ_clms;
public class Test {
public static void main(String[] args) {
String type="打8折";
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;
}
double totalPrices=0;
totalPrices=cc.GetResult(100)*10;
System.out.println("合计:"+totalPrices);
}
}
法2:策略模式+简单工厂模式
package DHSJ_clms;
public class CashContext {
private CashSuper cashsuper;
public CashContext(String type)
{
switch(type)
{
case "正常收费":
cashsuper=new CashNormal();//默认有无参的构造函数
break;
case "满300返100":
cashsuper=new CashReturn("300","100");
break;
case "打8折":
cashsuper=new CashRebate("0.8");
break;
}
}
public double GetResult(double money)
{
return cashsuper.acceptCash(money);
}
}
package DHSJ_clms;
public class Test {
public static void main(String[] args) {
CashContext cc=new CashContext("打8折");
double totalPrices=0;
totalPrices=cc.GetResult(100)*10;
System.out.println("合计:"+totalPrices);
CashContext cp=new CashContext("正常收费");
totalPrices+=cp.GetResult(100);
System.out.println("合计:"+totalPrices);
}
}
法1在客户端判断用哪一种算法,不好。
法2的CashContext类仍用到了switch,也不好,但可以用反射解决。(我学会了再重写一遍)



