策略模式--实现商场打折

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aimin_com/article/details/83035994

前言:
上一篇博客中写明了简单工厂的引用,其实这篇博客和上一篇类似,是利用了策略加简单工厂的方法实现的。为了我们的重构可以运用上设计模式,本次运用了客户端的形式展现出来,具体请往下看:

策略模式:
顾名思义即是:我提供不同的策略然后你自己选择即可。

定义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

小提示:
面向对象编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。

请看类图

其中CashContext和CashSuper是聚合的关系,因为关联关系在VS中显示不出来。
在这里插入图片描述

下面请揭晓真正的代码(Windows)

First:父子关系类

  /// <summary>
        /// 现金收费抽象类
        /// </summary>
        abstract class CashSuper
        {
            public abstract double acceptCash(double money);
            //现金收取超类的抽象方法,收取现金,参数为原价,返回为当前价
        }


        /// <summary>
        /// 正常收费子类
        /// </summary>
        class CashNormal : CashSuper
        {
            public override double acceptCash(double money)
            {

                //正常收费,原价返回
                return money;
            }
        }
        /// <summary>
        /// 打折收费子类
        /// </summary>
        class cashRebate : CashSuper
        {
            private double moneyRebate = 1d;
            public cashRebate(string moneyRebate)
            {
                //打折收费,初始化时,必需要输入折扣率,如八折,就是0.8
                this.moneyRebate = double.Parse(moneyRebate);

            }
            public override double acceptCash(double money)
            {
                return money * moneyRebate;
            }
        }
        /// <summary>
        /// 返利收费子类
        /// </summary>
        class CashReturn : CashSuper
        {
            private double moneyCondition = 0.0d;
            private double moneyReturn = 0.0d;

            //返利收费,初始化时必须要输入返利条件和返利值,比如满300反100,则moneyCondition为300,monneyRetrun为100
            public CashReturn(string moneyCondition, string moneyReturn)
            {
                this.moneyCondition = double.Parse(moneyCondition);
                this.moneyReturn = double.Parse(moneyReturn);
            }
            public override double acceptCash(double money)
            {
                double result = money;

                //若大于返利条件,则需要减去返利值
                if (money >= moneyCondition)
                {
                    result = money - Math.Floor(money / moneyCondition) * moneyReturn;
                }
                return result;
            }
        }

Secend: 添加一个工厂:

       /// <summary>
        /// CashContext类
        /// </summary>
    class CashContext
    {
         CashSuper  cs = null;
         public CashContext(string type)
         {
             switch (type )
             {
                 case "正常收费":
                     CashNormal cs0 = new CashNormal();
                     cs = cs0;
                     break;
                 case "满300反100":
                     CashReturn cr1 = new CashReturn("300", "100");
                     cs = cr1;
                     break;
                 case "打8折":
                     cashRebate cr2 = new cashRebate("0.8");
                     cs = cr2;
                     break;
             }

         }
              
        //根据收费策略的不同,获得计算结果
        public double GetResult(double money)
        {
            return cs.acceptCash(money);
        }
    }

添加一个自动加载

 //设置自动加载:只要是下拉框
        private void Form1_Load(object sender, EventArgs e)
        {
            cbxType.Items.AddRange(new object[] { "正常收费", "满300反100", "打8折"});
            cbxType.SelectedIndex = 0;
        }

在客户端确定按钮中:

       //客户窗体程序
        double total = 0.0d;// 用于总计
        private void btnOk_Click(object sender, EventArgs e)
        {

            CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());
            double totalprices = 0d;

            totalprices = csuper.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
                //通过对Context的GetResult方法的调用,可以得到收取费用的结果,让具体算法与客户进行了隔离

            total = total + totalprices ; //将每个商品合计计入总计。

            lbxList.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text + "合计:" + totalprices.ToString ());
                //通过多态,可以得到收取费用的结果。

            lblResult.Text = total.ToString();  //lab标签上显示总数量            
            
        }

以下就是制作的代码界面,前面的计算器没有给出,这次补上:
在这里插入图片描述

小结:
本次打折如果想添加其他优惠情况,则直接添加一个新类继承接口即可,并在工厂里面添加一个 case做为选择并在下拉框中显示出来即可。

基本策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象,只是我用了一个工厂将客户端的选择放进了Context中,相当于用了分治算法将复杂问题给分开。

猜你喜欢

转载自blog.csdn.net/aimin_com/article/details/83035994
今日推荐