策略模式 -- 大话设计模式

在今天,读书有时是件“麻烦”事。它需要你付出时间,付出精力,还要付出一份心境。--仅以《大话设计模式》来祭奠那逝去的……

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

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));
        }
    }

 

posted @ 2015-10-27 16:59  荒古禁地  阅读(163)  评论(0编辑  收藏  举报