昨天学习了简单工厂模式,通过对书中代码的编写,加深了对其的理解,今天学习策略模式
需求:某商场需要一个收银软件,但是它的商品有时是正价,有时是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 }