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分支中不断的增加肯能出现的情况。

      

  • 相关阅读:
    Cefsharp 75 设置代理
    C# Winform 执行JS脚本
    Cefsharp 75 为每个实例单独设置缓存目录
    QQ邮箱发送邮件,出现mail from address must be same as authorization user错误
    软件卸载后自动重装,服务器中了流氓软件解决方法
    win版宝塔更新后,宝塔无法启动(修复办法)
    C的typedef
    为Arch Linux安装桌面
    在Simplicity Studio下创建适用于EFR32的工程项目
    在VMWare上安装Arch Linux
  • 原文地址:https://www.cnblogs.com/charging-for-ycp/p/7366135.html
Copyright © 2011-2022 走看看