• 策略模式


    查看本人文章索引请通过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,因此他们区别是目的不同,一个是为了返回实例,一个是为了封装不同的算法,适应算法的变化。

  • 相关阅读:
    两台独立计算机共享一套键鼠
    【不要太监,成为笑话】拼搏百天,我要成为程序员!键盘敲烂,我要月薪过万!第三天
    【不要太监,成为笑话】拼搏百天,我要成为程序员!键盘敲烂,我要月薪过万!第二天
    【不要太监,成为笑话】拼搏百天,我要成为程序员!键盘敲烂,我要月薪过万!第一天
    javac编译时报错 (错误: 编码GBK的不可映射字符)
    JavaWeb学习1-springMVC
    理学和工学的区别
    各种证书
    问题
    字符编码的理解
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2497558.html
Copyright © 2020-2023  润新知