策略模式 -- 大话设计模式
在今天,读书有时是件“麻烦”事。它需要你付出时间,付出精力,还要付出一份心境。--仅以《大话设计模式》来祭奠那逝去的……
策略模式就是用来封装算法的。实践中,我们发现可以用它来封装几乎任何类型的规则,只要分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
1.商场促销活动
实现商场促销活动,正常收费、满300返100和打8折活动
首先我们定义一个收费抽象类,包含一个收取现金抽象方法
/// <summary> /// 收费抽象类 /// </summary> public abstract class Fee { /// <summary> /// 收取现金抽象方法 /// </summary> public abstract double AcceptCash(double money); }
然后实现我们需要的算法:正常收费和打折收费,让其继承收费抽象类,重写AcceptCash方法实现不同的收费算法(如果我们以后要增加其他收费方法,只需要新增一个继承Fee收费抽象类的子类,实现其收费算法,而无需变动已经写好的算法)
/// <summary> /// 正常收费 /// </summary> public class FeeNormal : Fee { public override double AcceptCash(double money) { return money; } } /// <summary> /// 打折收费 /// </summary> public class FeeRebate : Fee { private double moneyRebate = 1; public FeeRebate(double moneyRebate) { this.moneyRebate = moneyRebate;//打折比率,例如:打8折为0.8 } public override double AcceptCash(double money) { return moneyRebate * money; } }
下面定义两个收费策略上下文类。第一个是结合简单工厂模式后,将判断使用那种算法转移到了策略上下文中,同时客户端调用的时候同比简单工厂模式暴漏的类更少,客户端只需要认识FeeContext就好了,耦合度更低;第二个是未结合简单工厂模式的策略上下文,客户端使用它需要自己判断到底使用哪种算法,不够灵活,扩展性不强
/// <summary> /// 收费策略上下文(结合简单工厂) /// </summary> public class FeeContext { Fee fee = null; public FeeContext(string type) { switch (type) { case "正常收费": fee = new FeeNormal(); break; case "打8折": fee = new FeeRebate(0.8); break; } } public double AcceptCash(double money) { return fee.AcceptCash(money); } } /// <summary> /// 收费策略上下文 /// </summary> public class FeeContext2 { Fee fee = null; public FeeContext2(Fee fee) { this.fee = fee; } public double AcceptCash(double money) { return fee.AcceptCash(money); } }
最后是客户端调用,这里只展示了结合简单工厂模式后的调取方式
class Program { static void Main(string[] args) { FeeContext feeContext = new FeeContext("打8折"); Console.WriteLine(feeContext.AcceptCash(1000)); } }