首页 > 代码库 > 策略模式

策略模式

  昨天学习了简单工厂模式,通过对书中代码的编写,加深了对其的理解,今天学习策略模式

  

  需求:某商场需要一个收银软件,但是它的商品有时是正价,有时是8折,5折或者满300减100

  

  看如下代码

  现金收费抽象类

1 public abstract class CashSuper
2     {
3         public abstract double GetCashSuper(double money);
4     }

  打折收费子类

 1 public class CashRebate:CashSuper
 2     {
 3         private double cash = 1d;
 4 
 5         public CashRebate(double cash)
 6         {
 7             this.cash = cash;//打折利率
 8         }
 9         public override double GetCashSuper(double money)
10         {
11             return money * cash;
12         }
13     }

  返利收费子类

public class CashReturn : CashSuper
    {
        private double moneyCondition = 0.0d;
        private double moneyReturn = 0.0d;

        public CashReturn(double moneyCondition, double moneyReturn)
        {
            this.moneyCondition = moneyCondition;//满多少
            this.moneyReturn = moneyReturn;//减多少
        }

        public override double GetCashSuper(double money)
        {
            double result = money;
            if (money > this.moneyCondition)
                result = money - Math.Floor(money/moneyCondition)*moneyReturn;
            return result;
        }
    }

  CashContext类

 1 class CashContext
 2     {
 3         private CashSuper cs;
 4 
 5         public CashContext(CashSuper cs)
 6         {
 7             this.cs = cs;
 8         }
 9 
10 
11         public double GetCashSuper(double money)
12         {
13             return cs.GetCashSuper(money);
14         }
15     }

  客户端

 1 CashContext context = null;
 2 
 3             string type = "满300减100";
 4             switch (type)
 5             {
 6                 case "正常收费":
 7                     context = new CashContext(new CashRebate(1));
 8                     break;
 9                 case "打5折":
10                     context = new CashContext(new CashRebate(0.5));
11                     break;
12                 case "满300减100":
13                     context = new CashContext(new CashReturn(300,100));
14                     break;
15             }
16 
17             double result = context.GetCashSuper(700);

  但是这样写的话,又在客户端去判断用哪个算法,我们使用策略与简单工厂结合将这个判断从客户端移除

  策略与简单工厂结合(改造CashContext)

 1 class CashContext
 2     {
 3         private CashSuper cs;
 4 
 5 
 6         public CashContext(string type)
 7         {
 8             switch (type)
 9             {
10                 case "正常收费":
11                     cs = new CashRebate(1);
12                     break;
13                 case "打8折":
14                     cs = new CashRebate(0.8);    
15                     break;
16                 case "满300减100":
17                     cs = new CashReturn(300, 100);
18                     break;
19             }
20         }
21 
22         public double GetCashSuper(double money)
23         {
24             return cs.GetCashSuper(money);
25         }
26     }

  改造后客户端代码

1  CashContext context = new CashContext("满300减100");
2 
3 
4             double result = context.GetCashSuper(700);

 

  用简单工厂模式和策略模式分别实现上述功能,简单工厂模式在客户端需要声明两个类,而策略模式之需要在客户短声明一个类(CashContext),耦合度更低

 

   策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以使用策略模式处理这种变化的可能性.

 1 /// <summary>
 2         /// 我觉得这个方法是区别与简单工厂模式的根本方法
 3         /// 简单工厂模式需要在客户端声明抽象基类,通过基类调用子类重写的方法
 4         /// 策略模式中,通过实例化本类,通过本类调用重写的方法
 5         /// </summary>
 6         /// <param name="money"></param>
 7         /// <returns></returns>
 8         public double GetCashSuper(double money)
 9         {
10             return cs.GetCashSuper(money);
11         }

 

策略模式