读《大话设计模式》笔记之一——简单工厂模式

时间:2021-01-14 20:33:53

读《大话设计模式》笔记之一——简单工厂模式

《大话设计模式》这是一本讲设计模式的书。虽说图书市场上关于设计模式的书籍有很多,但是适合入门学员看的却很少。而 《大话设计模式》以大家喜闻乐见的戏说的方式来讲高深的设计模式,的确打消了好多入门学员的畏难心理,而且书的价格也很便宜。的确说得上是物美价廉。如果您对这本书很感兴趣的话,可以去作者的博客(http://cj723..cnblogs.com/)上去看看,有意外的惊喜哟。

好了,言归正传,我准备将这本书中的一些重点将它罗列总结出来,供自己以后使用。

这本书的第一章讲的是设计模式中最简单的模式——简单工厂,和其它讲模式的书籍不同;一般书籍讲模式的时候总是先是一大篇的理论,然后给一个示例就完了。而本书的作者引用了《重构与模式》中的一句话:“如果想成为一名更优秀的软件设计师,了解优秀软件设计的演变过程比学习优秀设计本身更有价值,因为设计的演变过程中蕴藏了大智慧。”所以作者在讲模式的时候都是从一个普通的代码出发,不断的演变改进,让读者体会到如何将模式应用到这些普通代码中,使其透露出模式的光芒。好了现在我们一起来看一下作者如何演变简单工厂模式的。

首先作者给出了一段计算器的代码

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.Write("请输入数字A:");
                string strNumberA = Console.ReadLine();
                Console.Write("请选择预算符号(+、-、*、/):");
                string strOperate = Console.ReadLine();
                Console.Write("请输入数字B:");
                string strNumberB = Console.ReadLine();
                string strResult = "";
                switch(strOperate)
                {
                    case "+":
                        strResult = Convert.ToString(Convert.ToDouble(strNumberA)
                            + Convert.ToDouble(strNumberB));
                        break;
                    case "-":
                        strResult = Convert.ToString(Convert.ToDouble(strNumberA)
                            - Convert.ToDouble(strNumberB));
                        break;
                    case "*":
                        strResult = Convert.ToString(Convert.ToDouble(strNumberA)
                            * Convert.ToDouble(strNumberB));
                        break;
                     case "/":
                         if (strNumberB != "0")
                             strResult = Convert.ToString(Convert.ToDouble(strNumberA)
                                 / Convert.ToDouble(strNumberB));
                         else
                             strResult = "除数不能为0";
                        break;
                }
                Console.WriteLine("结果是:"+strResult);
                Console.ReadLine();
            }
            catch(Exception ex)
            {
                Console.WriteLine("您输入的有错:"+ex.Message);
            }
        }
    }

 

相信对上述代码大家一定很熟悉,每位学过编程的人都应该编写过类似的代码,接下来我们来看作者如何对这一代码做改动

class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.Write("请输入数字A:");
                string strNumberA = Console.ReadLine();
                Console.Write("请选择预算符号(+、-、*、/):");
                string strOperate = Console.ReadLine();
                Console.Write("请输入数字B:");
                string strNumberB = Console.ReadLine();
                string strResult = "";
                strResult = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumberA),
                    Convert.ToDouble(strNumberB), strOperate));

                Console.WriteLine("结果是:"+strResult);
                Console.ReadLine();
            }
            catch(Exception ex)
            {
                Console.WriteLine("您输入的有错:"+ex.Message);
            }
        }
    }

 public class Operation
    {
        public static double GetResult(double numberA, double numberB, string operate)
        {
            double result = 0d;

            switch (operate)
            {
                case "+":
                    result = numberA + numberB;
                    break;
                case "-":
                    result = numberA - numberB;
                    break;
                case "*":
                    result = numberA * numberB;
                    break;
                case "/":
                    result = numberA / numberB;
                    break;
            }
            return 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;
        }
    }

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;
        }
    }

class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.Write("请输入数字A:");
                string strNumberA = Console.ReadLine();
                Console.Write("请选择预算符号(+、-、*、/):");
                string strOperate = Console.ReadLine();
                Console.Write("请输入数字B:");
                string strNumberB = Console.ReadLine();
                string strResult = "";
                Operation operate=null;
                operate = OperationFactory.createOperate(strOperate);
               
                operate.NumberA = Convert.ToDouble(strNumberA);
                operate.NumberB = Convert.ToDouble(strNumberB);
                strResult = Convert.ToString(operate.GetResult());
                Console.WriteLine("结果是:" + strResult);
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine("您输入的有错:" + ex.Message);
            }
        }
    }

就这样作者顺利的引出了简单工厂模式