在大话设计模式中大鸟以收银台收银收账系统为例介绍了策略模式:
功能:
1.根据单品以及单品数量计算总价
2.打折处理
3.满减折扣处理。。。。
策略模式简介:
策略模式(Strategy),它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
此案例策略模式结构图:
CashSuper类,定义所有支持的算法的公共接口 (即策略类)
1 /// <summary> 2 /// 现金收费抽象类 3 /// <<策略算法类抽象类接口>> 4 /// </summary> 5 abstract class CashSuper 6 { 7 /// <summary> 8 /// 现金收费抽象方法 9 /// </summary> 10 /// <param name="money">实收金额</param> 11 /// <returns>返回当前价格</returns> 12 public abstract double AcceptCash(double money); 13 }
正常算法类 即不打折处理也没有返利 继承策略类并实现自己的算法功能
/// <summary> /// 正常收费类 算法类 /// </summary> class CashNormal:CashSuper//实现现金收费类接口 { /// <summary> /// 重写收费方法 /// </summary> /// <param name="money">实收金额</param> /// <returns>返回当前金额</returns> public override double AcceptCash(double money) { return money; } }
打折算法类, 继承策略类并实现自己的算法功能
1 /// <summary> 2 /// 打折类 算法类 3 /// </summary> 4 class CashRebate:CashSuper//继承现金收费类 5 { 6 double moneyRebate = 1d;//折扣率 7 //构造方法 需要传入一个折扣率 8 public CashRebate(double moneyRebate) 9 { 10 this.moneyRebate = moneyRebate; 11 } 12 /// <summary> 13 /// 实现折扣算法 14 /// </summary> 15 /// <param name="money">本来应收金额</param> 16 /// <returns>折扣后金额</returns> 17 public override double AcceptCash(double money) 18 { 19 return money * moneyRebate; 20 } 21 }
返利算法类,继承策略类并实现自己的算法功能
1 /// <summary> 2 /// 返利类 算法类 3 /// </summary> 4 class CashReturn:CashSuper//继承现金收费类 5 { 6 private double moneyCondition = 0; 7 private double moneyReturn = 0; 8 public CashReturn(double moneyCondition, double moneyReturn) 9 { 10 this.moneyCondition = moneyCondition; 11 this.moneyReturn = moneyReturn; 12 } 13 /// <summary> 14 /// 实现返利算法 15 /// </summary> 16 /// <param name="money"></param> 17 /// <returns></returns> 18 public override double AcceptCash(double money) 19 { 20 double result=money; 21 if (money > moneyCondition) 22 result = money - Math.Floor(money / moneyCondition) * moneyReturn; 23 24 return result; 25 } 26 }
策略模式上下文
1 /// <summary> 2 /// 上下文 3 /// </summary> 4 class CashContext 5 { 6 private CashSuper cs;//算法类基类 还可做工厂接受用 7 8 public CashContext(string CashType) 9 { 10 switch (CashType)//工厂方式创建不同的实例对象 11 { 12 case "normal": 13 cs = new CashNormal(); 14 break; 15 case "retrun": 16 cs = new CashReturn(300, 100); 17 break; 18 case "rebate": 19 cs = new CashRebate(0.8); 20 break; 21 } 22 23 } 24 /// <summary> 25 /// 统一的方法获得算法计算结果 26 /// </summary> 27 /// <param name="money"></param> 28 /// <returns></returns> 29 public double GetResult(double money) 30 { 31 return cs.AcceptCash(money); 32 }
上下文用来初始化策略对象,并根据策略对象调用策略方法
此处可以看到构造方法里面使用了简单工厂模式创建对象
调用
1 public class Program 2 { 3 public static void Main(string[] args) 4 { 5 //创建上下文 即策略并制定调用的策略算法类型 6 CashContext context = new CashContext("return");//调用的为满三百返利一百算法 7 Console.WriteLine("应收金额500,返利后应收:" + context.GetResult(500)); 8 } 9 }
结果:
总结:实例中结合了简单工厂模式,简单工厂模式体现在上下文的构造函数中,通过工厂获得不同的算法对象,并且根据需要执行的算法类型在上下文中得到相应算法计算后的结果,如后期需要添加新的算法,只需要添加一个算法的类继承算法策略类实现算法方法,并在上下文中添加算法类型即可调用。
从这个算法中可以看到和简单工厂很像,个人感觉简单工厂是动态获取到了不同的实例对象,而策略模式则是定义一系列算法的方法,可以通过统一的抽象类获取到不同的算法实现并可通过基类抽象类调用方法传递不同的算法得到不同的算法结果。
策略就是用来封装变化的,可把不同的实现都放在子类中,统一的通过父类来调用。