设计模式之策略模式

  何为策略模式?

    同一件事情,不同的类型,需要不同的策略去处理。就如书中所说的 “商场超市的促销方式”。 实际上,该功能如果用“简单工厂模式”也可以实现,不过有一些缺点。

    比如:因为商场超市的促销方式比较多,打折的话,就有“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分支中不断的增加肯能出现的情况。

  

原文地址:https://www.cnblogs.com/charging-for-ycp/p/7366135.html