zoukankan      html  css  js  c++  java
  • 设计模式之策略模式

      何为策略模式?

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

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

      

  • 相关阅读:
    windows 资源管理器 运行非常缓慢或者无反应的解决办法
    RPC工作原理
    如何解决访问某些网站会跳出对话框标题为:address Book Viewer ,提示:"无法连接制定的目录服务.服务也许暂时不可用,或服务器名称不正确。"
    运行程序的时候出错MFC42D.dll找不到。
    谷歌金山词霸合作版升级后出现CBSText.dll故障
    Network drives trying to connect when offline
    解决任务挂起或冻结在Windows XP
    打开word或者office程序报错:Microsoft Visual C++ Runtime Library. Runtime Error!
    恢复officescan控制台密码
    excel中同时冻结窗格--冻结行列标题
  • 原文地址:https://www.cnblogs.com/charging-for-ycp/p/7366135.html
Copyright © 2011-2022 走看看