设计模式之简单模式与策略模式

来源:互联网 发布:c语言视频下载 编辑:程序博客网 时间:2024/06/05 15:36

        最近在学习简单工厂模式与策略模式时,发现他们有很多相同之处,他们都是通过多态来实现不同子类的选取,比较难分辨,于是做了一下总结。

      简单工厂模式用于比如算法之于加减乘除、水果之于苹果梨香蕉、文具之于笔尺,这些例子的共同特点就是具体、数量有限,不涉及复杂的算法,简单工厂模式只是解决了对象的创建问题,工厂类中封装了所有的选择过程,如果对象要增加、减少、变化,就要改动工厂,以至于代码的重写量增大,并且在操作过程中,客户需要指定一个参数给工厂,工厂按照参数选择出需要实例化的派生类。在简单工厂模式中,客户需要知道抽象基类和工厂类,工厂类用来生成对象,使用抽象基类的接口来完成工作。它的核心是“简单模式是用来封装所有对象的”。

      下面是一个简单工厂模式的例子:

       

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 ();                    }    }}
          大家通过这两段代码和我的描述应该对这两种模式有所了解了,理解的还不够深刻,希望大家多多指出!

0 0
原创粉丝点击