設計模式-策略模式結合簡單工廠

前言:
策略模式可以定義一系列的算法,並且根據需求選擇算法。算法之間還可以相互替換,不影響客戶端的使用。
需求:
還是以商場的收銀系統爲例,這次添加一個需求。在上一個需求上加一個,打5折和打7折的需求。
類圖:
在這裏插入圖片描述
實現:
抽象策略類(沒有具體的實現策略,而是把具體策略的共同方法抽象到裏面)

/// <summary>
    /// 現金收費的抽象類,父類。
    /// </summary>
    abstract class CashSuper
    {
        /// <summary>
        /// 現金收費的抽象方法
        /// </summary>
        /// <param name="money">原價</param>
        /// <returns>當前價格</returns>
        public abstract double acceptCash(double money);
    }//end CashSuper

正常收費策略(繼承抽象策略類)

 /// <summary>
     /// 正常收費子類
     /// </summary>
    class CashNormal : CashSuper
    {
        /// <summary>
        /// 重寫父類的收費方法
        /// </summary>
        /// <param name="money">原價</param>
        /// <returns>當前價格</returns>
        public override double acceptCash(double money)
        {
            return money;//原價返回
        }//end acceptCash
    }//end CashNormal

打折策略(繼承抽象策略類)

/// <summary>
    /// 打折收費子類
    /// </summary>
    class CashRedbate : CashSuper
    {
        private double moneyRebate = 1d;//具體打幾折
        /// <summary>
        /// 獲取具體打幾折
        /// </summary>
        /// <param name="moneyRebate">具體打幾折</param>
        public CashRedbate(string moneyRebate)
        {
            this.moneyRebate = double.Parse(moneyRebate);
        }//end CashRedbate
        /// <summary>
        ///打折的方法
        /// </summary>
        /// <param name="money">原價</param>
        /// <returns>打折之後的價格</returns>
        public override double acceptCash(double money)
        {
            //原價*具體打折數=打折之後的價格
            return money * moneyRebate;
        }//end aceptCash
    }//end CashRedbate

返利策略(繼承抽象策略類)

    /// <summary>
    /// 返利收費子類
    /// </summary>
    class CashReturn : CashSuper
    {
        private double moneyCondition = 0.0d;//返利條件
        private double moneyReturn = 0.0d;//反多少
        /// <summary>
        /// 返利條件初始化
        /// </summary>
        /// <param name="moneyCondition">返利條件</param>
        /// <param name="moneyReturn">反多少</param>
        public CashReturn(string moneyCondition, string moneyReturn)
        {
            this.moneyCondition = double.Parse(moneyCondition);//返利條件
            this.moneyReturn = double.Parse(moneyReturn);//反多少
        }//end CashRetur
        /// <summary>
        /// 返利計算方法
        /// </summary>
        /// <param name="money">原價</param>
        /// <returns>返利之後的價格</returns>
        public override double acceptCash(double money)
        {
            double result = money;//要返回的價格
            //判斷是否滿足返利的要求
            if (money >= moneyCondition)
            {
                result = money - Math.Floor(money / moneyCondition) * moneyReturn;

            }//end if
            return result;//返回價格
        }//end AcceptCash
    }//end CashReturn

客戶端(在客戶端用switch選擇具體的策略,把選好的具體策略傳入CashFactoury裏面。然後根據傳進去的策略進行具體的計算。)

             double total = 0.0d;
        private void butok_Click(object sender, EventArgs e)
        {
             CashContext cc = null;//實例化策略模式
            //根據條件選擇策略
             switch (cbxType.Selecteditem.Tostring())
            {
                case "正常收費":
                    cc = new CashNormal();
                    break;
                case "滿300返100":
                    cc = new CashReturn("300", "100");
                    break;
                case "打8折":
                    cc = new CashRedbate("0.8");
                    break;
                case "打5折":
                    cc = new CashRedbate("0.5");
                    break;
                case "打7折":
                    cc = new CashRedbate("0.7");
                    break;
            }//end switch
            
            double totalprices = 0d;//金額
            totalprices = cc.GetResult(Convert.ToDouble(txtNumber1.Text )
                *Convert.ToDouble(txtNumber2.Text));
            //累加
            total = total + totalprices;
            listBox1.Items.Add("單價:" + txtNumber1.Text + "數量:" + txtNumber2.Text + "\t" +
           combType.SelectedItem + "合計:" + totalprices.ToString());
            lblmony.Text = total.ToString();
        }
        }//end createCashAccept

反思:
在第一個簡單工廠模式我們就把客戶端的判斷部分移動到了後端,但是在策略模式這裏我們又把判斷部分移到了客戶端。讓客戶端來選擇具體使用哪個策略。
解決方案:
我們可以把策略模式和簡單工廠模式結合使用,這樣即解決了算法可以靈活替換還把選擇部分又移動到了後端。
策略模式+簡單工廠模式:(只需要修改原來的CashFactory類和客戶端代碼)
CashFactory類

 class CashFactory
    {
        CashSuper cs = null;//實例化父類
        /// <summary>
        /// 根據需要實例化對象
        /// </summary>
        /// <param name="type">需要實例化的對象名</param>
        /// <returns>返回實例化之後的對象</returns>
        public  CashFactory(string type)
        {
            //判斷選擇了哪種優惠方案
            switch (type)
            {
                case "正常收費":
                    cs = new CashNormal();
                    break;
                case "滿300返100":
                    cs = new CashReturn("300", "100");
                    break;
                case "打8折":
                    cs = new CashRedbate("0.8");
                    break;
                case "打5折":
                    cs = new CashRedbate("0.5");
                    break;
                case "打7折":
                    cs = new CashRedbate("0.7");
                    break;
            }//end switch
             
        }//end createCashAccept
        /// <summary>
        /// 根據具體實例化對象,調用方法。
        /// </summary>
        /// <param name="money">原價</param>
        /// <returns>當前價格</returns>
        public double GetResult(double money)
        {
            return cs.acceptCash(money);
        }//end GetResult
    }//end class CashFactory

客戶端(修改之後的)

       double total = 0.0d;
        private void butok_Click(object sender, EventArgs e)
        {
        //實例化策略工廠類
            CashFactory cc = new CashFactory(combType.SelectedItem.ToString());
            double totalprices = 0d;//金額
            totalprices = cc.GetResult(Convert.ToDouble(txtNumber1.Text )
                *Convert.ToDouble(txtNumber2.Text));
            //累加
            total = total + totalprices;
            listBox1.Items.Add("單價:" + txtNumber1.Text + "數量:" + txtNumber2.Text + "\t" +
           combType.SelectedItem + "合計:" + totalprices.ToString());
            lblmony.Text = total.ToString();
        }

結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章