设计模式:1-2章

前言:短暂的春节过去了,我又要开始新的学习了。虽然寒假短暂,但说实话在家里呆着不知道干什么的滋味的确有些不适应:每天只能抽出不到一个小时的时间背单词,背完之后又没有其他学习资料(计算机类学习)来换换思维。

长话短说,既然开始了学习,那么我们就步入正题吧:今天要总结的是自己假期前看到的设计模式:1-2章。

说到设计模式之前,我们不可避免的还是要提到面向对象。为什么我们在编写代码时,要使用面向对象呢?换而言之,面向对象的优点是什么呢?面向对象的优点:降低程序的耦合度,使程序更加灵活、易于修改与复用。而如何体现这种优点呢:通过设计模式来体现。

第一章:简单工厂模式

在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。              

1.简单工厂模式包含如下三种结构:

-工厂类:负责实现具体产品类中的实例。工厂类可以被外界直接调用,创建所需的产品对象。

-抽象产品类:是所有具体产品类的父类,负责描述所有实例所共有的接口

-具体产品类:继承于抽象产品类

                                                                                                            ---以上概念摘自Bobby0322的博客,感谢巨人

简单来讲,就是工厂类实例化抽象工厂类中的具体产品类。整个过程大致可以由三部分组成:第一部分是工厂类,工厂类实例化各个具体产品类,可以使用他们的计算方法,并方便主程序对其直接调用;第二部分是抽象产品类,通过抽象方法定义,以方便其下的子类重写方法;第三部分就是具体产品类,这些类使用override重写父类方法。

2.简单工厂模式结构图:

第二章:策略模式

策略模式所体现的思想是具有类似功能的算法可以进行相互替换。

1.策略模式(Strategy)结构图:

2.策略模式的优点:策略模式可以灵活的添加或改变新的策略,对于代码的封装性、复用性都有很大的体现。

以上两种设计模式都充分使用到了继承与封装这两个概念。

例子:超市会不定期举行促销活动,假设超市一共有三种结算方式:正常收费、满300减100、打8折这三种,如何用简单工厂与策略模式设计一个结算界面呢?

主界面:

父类:收费

    //抽象收费父类
    abstract class CashSuper
    {
        public abstract double acceptCash(double money);//抽象父类方法
    }

子类:正常收费

    //正常收费子类
    class CashNormal:CashSuper
    {
        public override double acceptCash(double money)//重写父类方法
        {
            return money;
        }
    }

子类:满减

    //满减
    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 CashRebate : CashSuper
    {
        public double moneyRebate = 1d;
        public CashRebate(string moneyRebate)//构造方法
        {
            this.moneyRebate = Convert.ToDouble(moneyRebate);
        }

        public override double acceptCash(double money)//重写父类方法
        {
            return money * moneyRebate;
        }
    }

简单工厂+Context上下文(关键点)

    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 GerResult(double money)//输出结果到主程序
        {
            return cs.acceptCash(money);
        }
    }

主程序:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
       
        double total = 0.0d;//定义初始总价为0
        private void btnOK_Click(object sender, EventArgs e)
        {
            CashContext csuper = new CashContext(cmbType.SelectedItem.ToString());//实例化context上下文类
            double totalPrices = 0d;//定义购物总价
            totalPrices = csuper.GerResult(Convert.ToDouble(txtPrice.Text)*Convert.ToDouble(txtNum.Text));//计算价格,此步骤需要跳转至context类得到金钱的值

            total = total + totalPrices;
            cbxType.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text + "" + cmbType.SelectedItem + "合计:" + totalPrices.ToString());//显示
            lblResult.Text = total.ToString();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cmbType.Items.Add("正常收费");
            cmbType.Items.Add("满300减100");
            cmbType.Items.Add("打8折");
        }
    }

代码运行步骤:(蓝色代表类,红色代表变量,绿色代表方法)

-运行,输入单价为100、数量为1、计算方式为8折,之后点击确定。

-首先实例化CashContext类,在CashContext中实例化收费父类cs。(在之后对收费类的调用其实都是通过父类调用)

-判断计算方式为打8折,之后通过构造函数的方式将“0.8”赋值给CashRebate子类中的moneyRebate

-然后回到主程序,变量totalPrices计算,并通过构造函数将输入的“100”赋值给CashContext类中的money变量,CashContext再通过CashSuper父类调用Rebate子类,重写父类方法acceptCash,进行money*moneyRebate的运算,并通过GerResult方法返回结果给主程序

-主程序输出

输出结果:

这个例子所体现的简单工厂策略不用多说,我们来讲一下这个例子有关策略模式的内容:

每当超市不定期举行活动,如从正常收费变为打八折,这时我们只需要更改相应的策略即可;而若是超市增加了“打75折”这样的促销活动时,也不必担心,我们只需要新写一个子类,在Context中增加新选项,并在主程序中的下拉框中写入一个新的即可,而不需要修改任何计算公式。因为数值类的计算公式没有被写死,而是通过传值的方式进行计算。这种策咯模式减少了对代码的修改,也提高了代码的复用性。

猜你喜欢

转载自blog.csdn.net/Marshallren/article/details/86797814
1-2
今日推荐