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

    查看本人文章索引请通过http://www.cnblogs.com/seesea125/archive/2012/04/17/2453256.html

    一、定义

    策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

    无标题

    二、概述

    应用场景:

      1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。

      2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。

      3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

    三、代码实现

    需求:商场收费系统,根据商品的单价和数量,得出的总结可以"正常收费", "打八折","满300返100", "打七折", "打五折"等等。

    代码如下:

    复制代码
    abstract class CashSuper
       {
           public abstract double acceptCash(double money);
       }
       //正常收费子类
       class CashNormal : CashSuper
       {
           public override double acceptCash(double money)
           {
               return money;
           }
       }
       //打折收费子类
       class CashRebate : CashSuper
       {
           private double moneyRebate = 1d;
           public CashRebate(string moneyRebate)
           {
               this.moneyRebate = double.Parse(moneyRebate);
           }
           public override double acceptCash(double money)
           {
               return money*moneyRebate;
           }
       }
       //返利收费子类
       class CashReturn : CashSuper
       {
           private double moneyCondition = 0.0d;
           private double moneyReturn = 0.0d;
           public CashReturn (string moneyCondition,string moneyReturn)
           {
               this.moneyCondition=double.Parse(moneyCondition);
               this.moneyReturn=double.Parse(moneyReturn);
           }
    
           public override double acceptCash(double money)
           {
               double result = money;
               if (money >= moneyCondition)
                   result = money - Math.Floor(money / moneyCondition) * moneyReturn;
               return result;
           }
       }
    复制代码


    Context类:

    复制代码
    class CashContext
        {
            private CashSuper cs;
            public CashContext(string type)
            {
                switch (type)
                { 
                    case "正常收费":
                        CashNormal cs0=new CashNormal();
                        cs=cs0;
                        break;
                    case "满300返100":
                        CashReturn cr1 = new CashReturn("300","100");
                        cs = cr1;
                        break;
                    case "打八折":
                        CashRebate cr2 = new CashRebate("0.8");
                        cs = cr2;
                        break;
                }            
            }
    
            public double GetResult(double money)
            {
                return cs.acceptCash(money);
            }
        }
    复制代码

    客户端调用:

    CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());
    double totalPrices = 0d;
    totalPrices = csuper.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));

    四、和工厂的区别:

    上面代码也可以用工厂方法实现,不过策略和工厂的区别很大。

    如果用工厂实现,核心工厂是这样的,其他地方代码不变:

    复制代码
    class CashFactory
        {
            public static CashSuper createCashAccept(string type)
            {
                CashSuper cs = null;
                switch (type)
                { 
                    case "正常收费":
                        cs = new CashNormal();
                        break;
                    case "满300返100":
                        cs = new CashReturn("300", "100");
                        break;
                    case "打八折":
                        cs = new CashRebate("0.8");
                        break;
                }
                return cs;            
            }
        }
    复制代码

    使用工厂的时候,客户端调用

    CashSuper csuper = CashFactory.createCashAccept(cbxType.SelectedItem.ToString());            
    double totalPrices = 0d; //工厂模式解决方案 totalPrices = csuper.acceptCash(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));


    可见两种实现,他们代码很类似,大概的只是多了一个方法

    public double GetResult(double money)
    {
    return cs.acceptCash(money);
    }


    由此可见他们的区别:他们返回的内容不同,工厂是返回不同的实例给客户端,而策略的实例只是为了自己的类使用,他是根据参数返回算法的结果GetResult,因此他们区别是目的不同,一个是为了返回实例,一个是为了封装不同的算法,适应算法的变化。

  • 相关阅读:
    CentOS7.6下安装qt-creator
    chromedriver下载地址
    selenium 基于Autolt工具对于Windows窗口上传文件操作
    Selenium+java
    jmeter删除历史打开的脚本记录
    echarts 各种特效图
    SpringBoot启动-问题解决:Could not locate executable nullinwinutils.exe in the Hadoop binaries
    pinyin4j
    JMeter内存溢出:java.lang.OutOfMemoryError: Java heap space解决方法
    selenium自动化测试中升级chrome78版本带来的问题
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2497558.html
Copyright © 2011-2022 走看看