閱讀970 返回首頁    go 阿裏雲 go 技術社區[雲棲]


設計模式之簡單模式與策略模式

        最近在學習簡單工廠模式與策略模式時,發現他們有很多相同之處,他們都是通過多態來實現不同子類的選取,比較難分辨,於是做了一下總結。

      簡單工廠模式用於比如算法之於加減乘除、水果之於蘋果梨香蕉、文具之於筆尺,這些例子的共同特點就是具體、數量有限,不涉及複雜的算法,簡單工廠模式隻是解決了對象的創建問題,工廠類中封裝了所有的選擇過程,如果對象要增加、減少、變化,就要改動工廠,以至於代碼的重寫量增大,並且在操作過程中,客戶需要指定一個參數給工廠,工廠按照參數選擇出需要實例化的派生類。在簡單工廠模式中,客戶需要知道抽象基類和工廠類,工廠類用來生成對象,使用抽象基類的接口來完成工作。它的核心是“簡單模式是用來封裝所有對象的”。

      下麵是一個簡單工廠模式的例子:

       

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 簡單工廠模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Operation oper;
            oper = OperationFactory.createOperate("+");
            oper.NumberA = 1;
            oper.NumberB = 4;
            double result = oper.GetResult();
            Console.WriteLine("結果是:" + result);

        }
        public class Operation//抽象類
        {
            private double _numberA = 0;
            private double _numberB = 0;

            public double NumberA
            {
                get { return _numberA; }
                set { _numberA = value; }
            }
            public double NumberB
            {
                get { return _numberB; }
                set { _numberB = value; }
            }
            public virtual double GetResult()
            {
                double result = 0;
                return result;
            }
        }
        class OperationAdd : Operation//基類:加法
        {
            public override double GetResult()
            {
                double result = 0;
                result = NumberA + NumberB;
                return result;
            }
        }
        class OperationSub : Operation//減法
        {
            public override double GetResult()
            {
                double result = 0;
                result = NumberA - NumberB;
                return result;
            }
        }
        class OperationMul : Operation//乘法
        {
            public override double GetResult()
            {
                double result = 0;
                result = NumberA * NumberB;
                return result;
            }
        }
        class OperationDiv : Operation//除法
        {
            public override double GetResult()
            {
                double result = 0;
                if (NumberB == 0)
                    throw new Exception("除數不能為0。");
                result = NumberA / NumberB;
                return result;
            }
        }
        //工廠類
        public class OperationFactory
        {
            public static Operation createOperate(string operate)
            {
                Operation oper = null;
                switch (operate )
                {
                    case "+":
                        oper = new OperationAdd();
                        break;
                    case "-":
                        oper = new OperationSub();
                        break;
                    case "*":
                        oper = new OperationMul();
                        break;
                    case "/":
                        oper = new OperationDiv();
                        break;
                }
                return oper;
            }

        }
    }
}
       由於產品對象形式經常改變,使用簡單工廠模式則會導致代碼重新編寫,而策略模式則避免了這一點,它定義了算法家族,分別封裝起來,讓他們之間可以相互替換,算法的變化不會影響到客戶對算法的使用,適用於大量複雜運算,它和簡單工廠模式的區別就是,它沒有工廠類,而是將工廠類的代碼寫到了客戶端,客戶端包括具有各種功能的代碼,策略模式在使用時首先要創建一個類,將該類的對象傳遞進去,通過該對象調用不同的算法,下麵的Context就是這個作用,它將使用選擇對象的工廠交給了使用該模式的用戶.它的核心是:策略模式是用來封裝算法的,但在實踐中,我們發現可以用它來封裝幾乎任何類型的規則,隻要在分析過程中遇到需要在不同時間應用不同的業務規則,就可以考慮使用策略模式處理這種變化的可能性.

       下麵是一段策略模式的例子:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ce
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            cbxType.Items.Add("正常收費");
            cbxType .Items .Add ("打折收費");
            cbxType .Items.Add ("返利收費");
        }
                private void btnOk_Click(object sender, EventArgs e)
        {
           CashSuper csuper=CashFactory .CreateCashAccept (cbxType.SelectedItem.ToString());
            
        }
           //現金收取抽象類
        abstract class CashSuper
        {
            public abstract double acceptCash(double money);
        }
        //正常收費子類
        class CashNormal:CashSuper
        {
            public override  double acceptCash(double money)
            {
                return money;
            }
        }
        //打折收費子類
        class CashRebate:CashSuper
        {
            private double moneyRebate = 1d;
            public CashRebate (string moneyRebate)
            {
                this.moneyRebate = double.Parse(moneyRebate);
            }
            public override double acceptCash(double money)
            {
                return money * moneyRebate;
            }
        }
        //返利收費子類
        class CashReturn:CashSuper
        {
            private double moneyCondition = 0.0d;
            private double moneyReturn = 0.0d;
            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;
            }
        }
        //現金收費工廠類
        class CashFactory
        {
            public static CashSuper CreateCashAccept(string type)//現金收取工廠
            {
                CashSuper cs=null;
                switch (type)
                {
                    case "正常收費":
                        cs=new CashNormal ();
                        break ;
                    case "滿300返100":
                        CashReturn cr1=new CashReturn ("300","100");
                        cs=cr1;
                        break ;
                    case "打8折":
                        CashRebate cr2=new CashRebate ("0.8");
                        cs=cr2;
                        break ;
                }
                return cs ;
            }
        }
        class CashContext
        {
            private CashSuper cs;//聲明一個CashSuper對象;

            public CashContext (CashSuper csuper)//通過構造方法,傳入具體的收費策略;
            {
                this.cs=csuper ;
            }
            public double GetResult(double money)
            {
                return cs.acceptCash (money );//根據收費策略不同獲得計算結果;
            }
        }

        //客戶端窗體程序
       
        double total=0.0d;
        private void bntOk_Click(object sender, EventArgs e)
        {
            CashContext cc=null ;
            switch (cbxType .SelectedItem .ToString ())
            {
                case "正常收費":
                    cc=new CashContext (new CashNormal ());
                    break;
                case "滿300返100":
                    cc=new CashContext (new CashReturn ("300","100"));
                    break ;
                case "打8折":
                    cc=new CashContext (new CashRebate ("0.8"));
                    break ;

            }
            CashSuper csuper = CashFactory.CreateCashAccept(cbxType.SelectedItem.ToString());
            double totalPrices=0d;
            //通過多態,可以得到收費的結果
            totalPrices =csuper .acceptCash (Convert .ToDouble(txtPrice .Text)*Convert.ToDouble (txtNum.Text ) );
            total=total+totalPrices;
            lbxList .Items.Add("單價:"+txtPrice.Text +"數量:"+txtNum.Text +" "+cbxType.SelectedItem +"合計:" +totalPrices .ToString ());
            lblResult.Text =total .ToString ();
            
        }
    }
}
          大家通過這兩段代碼和我的描述應該對這兩種模式有所了解了,理解的還不夠深刻,希望大家多多指出!

最後更新:2017-04-03 12:55:04

  上一篇:go android多屏幕分辨率適配
  下一篇:go android多屏幕分辨率適配