策略模式

策略模式是一种定义了一系列算法的方法,这些算法完成的都是类似的工作,只是实现不同,可以以相同的方法调用所有的算法,减少了各种算法类与使用算法类之间的耦合。一般只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性,下面用策略模式结合简单工厂模式实现商场的不同打折算法:

1 多种打折算法的实现

     /// <summary>
    /// 打折算法接口
    /// </summary>
    public abstract class CashSuperStrategy
    {
        public abstract double CashCaulate(double money);
    }

    /// <summary>
    /// 不打折算法
    /// </summary>
    public class CashNormalStrategy : CashSuperStrategy
    {
        public override double CashCaulate(double money)
        {
            return money;
        }
    }

    /// <summary>
    /// 打折算法
    /// </summary>
    public class CashRebateStrategy : CashSuperStrategy
    {
        private double rebate = 1d;

        public CashRebateStrategy(double cashRebate)
        {
            this.rebate = cashRebate;
        }

        public override double CashCaulate(double money)
        {
            return money * rebate;
        }
    }

    /// <summary>
    /// 满额返现算法
    /// </summary>
    public class CashReturnStrategy : CashSuperStrategy
    {
        private double moneyConditon = 0d;
        private double moneyReturn = 0d;

        public CashReturnStrategy(double moneyConditon, double moneyReturn)
        {
            this.moneyConditon = moneyConditon;
            this.moneyReturn = moneyReturn;
        }

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

2 引入Context类,根据客户端不同参数使用不同的算法 

    /// <summary>
    /// 结合策略模式和简单工厂模式
    /// </summary>
    public class Context
    {
        CashSuperStrategy strategy;

        /// <summary>
        /// 此处结合简单工厂模式,将实例化的职责由客户端转移到了Context类中
        /// 减轻了客户端的职责和客户端与算法类的耦合度
        /// </summary>
        /// <param name="discountType"></param>
        public Context(string discountType)
        {
            switch (discountType)
            {
                case "正常收费":
                    strategy = new CashNormalStrategy();
                    break;
                case "打7折":
                    strategy = new CashRebateStrategy(0.7);
                    break;
                case "满300返100":
                    strategy=new CashReturnStrategy(300,100);
                    break;
            }
        }

        public double GetResult(double money)
        {
            return strategy.CashCaulate(money);
        }
    }

3 客户端使用Context类,间接使用不同的算法

         /// <summary>
        /// 这种实现方法对于客户端,只需要认识Context类,完全不需要了解任何算法类,甚至不需要了解算法类的接口
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Context context1 = new Context("正常收费");
            double result1 = context1.GetResult(100);
            Console.WriteLine(result1);
            Console.ReadLine();

            Context context2 = new Context("打7折");
            double result2 = context2.GetResult(100);
            Console.WriteLine(result2);
            Console.ReadLine();

            Context context3 = new Context("满300返100");
            double result3 = context3.GetResult(300);
            Console.WriteLine(result3);
            Console.ReadLine();
        }

 

执行代码,运行结果为:

100

70

200

 

当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行。而将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。至于简单工厂中的条件语句则可以结合反射和配置文件解决。

 

posted @ 2016-04-06 15:31  angela217  阅读(270)  评论(0编辑  收藏  举报