关闭

大话设计模式-第01章 代码无错就是优?——简单工厂模式

标签: 简单工厂模式可维护可复用可扩展
325人阅读 评论(0) 收藏 举报
分类:

01 代码无错就是优?——简单工厂模式

    版本1:

        class Program

        {

            static void Main(string[] args)

            {

                Console.Write(“请输入数字A”);

                string A = Console.ReadLine();


                Console.Write(“请输入运算符号(+、-、*、/):”);

                string B = Console.ReadLine();


                Console.Write(“请输入数字B”);

                string C = Console.ReadLine();

                string D = “”;


                if (B == “+”)

                    D = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(C));

                if (B == “-”)

                    D = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(C));

                if (B == “*”)

                    D = Convert.ToString(Convert.ToDouble(A) * Convert.ToDouble(C));

                if (B == “/”)

                    D = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(C));


                Console.WriteLine(“结果是:” + D);

            }

        }

    以上代码至少存在以下3个问题:

        1:变量命名不规范。

        2:使用了四次 if 而不是if else结构,意味着做了多次无用功。

        3:没有对用户输入内容做合法性校验。


    版本2:

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

                }

            }

        }


1.4 面向对象编程

    很多人都有这样的问题:就是碰到问题就直觉地用计算机能够理解的逻辑来描述和表达待解决的问题及具体的求解过程。这其实就是用计算机的方式去思考,这样的思维使得我们的程序不易维护,不易扩展,更不易复用。


1.5 活字印刷,面向对象

    以活字印刷为例:第一,要改,只需要更改要改之字,此为可维护;第二,这些字并非这次用完就无用,完全可以在后来的印刷中重复使用,此乃可复用;第三,若要加字,只需要另外刻字加入即可,这是可扩展;第四:若要由横拍印刷转为竖排印刷,只要重新排序即可,此为灵活性好。


1.6 面向对象的好处

    通过封装、继承、多态把程序的耦合度降低。用设计模式使得程序更加的灵活,容易修改,并且易于复用。


1.8 业务的封装

    让业务逻辑与界面逻辑分开,让他们之间的耦合度下降。只有分离,才可以达到容易维护或扩展。

    版本3:

        Operation运算类:

        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;

            }

        }

    客户端代码

        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 = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumberA), Convert.ToDouble(strNumberB), strOperate));

                Console.WriteLine(“结果是:” + strResult);

                Console.ReadLine();

            }

            catch (Exception ex)

            {

                Console.WriteLine(“你的输入有错:”+ex.Message);

            }

        }


1.9 紧耦合VS松耦合

    观察上面的代码可发现,如果需要新增加一种运算类型,将会很麻烦,需要修改原有的运算类。

    版本41:

        Operation 运算类

        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;

            }

        }


1.10 简单工厂模式

    现在的问题是实例化哪个对象的问题,到底是实例化谁,将来会不会增加实例化的对象,比如增加开根运算,这是很容易变化的地方,可以考虑用一个单独的类来做这个创造实例的过程,这就是简单工厂。

    版本42:

        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;

            }

        }


    客户端代码:

        Operation oper;

        oper = OperationFactory.createOperate(“+”);

        oper.NumberA = 1;

        oper.NumberB = 2;

        double result = oper.GetResult();


    此时如果需要增加新运算只需要增加运算累和修改简单工厂类即可。

    结构图:

简单工厂类结构图.tiff

    其中空心三角形+实线表示继承关系,箭头+虚线表示依赖(dependency)关系


    简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。但是简单工厂模式违反了开放-封闭原则,如果要添加新的产品就要修改简单工厂类,这就等于说,我们不但对扩展开放,对修改也开放。

method |ˈmeθəd| noun:方法.

    工厂方法模式(Factory Method),定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。工厂方法模式实现时,客户端需要决定实例化那一个工厂来生产产品,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移动到了客户端代码来进行。你想要加功能,本来是改工厂类的,而现在是修改客户端。



1void |vɔɪd| noun:空白、空虚。

2console |ˈkɒnsəʊl| noun(control panel)控制面板、(control system)控制台。

3convert |kənˈvɜːt| verb:转变、换算。

4exception |ɪkˈsepʃn| noun:例外。

5switch |swɪtʃ| noun:开关。

6salary |ˈsæləri| noun:薪水。

7override |ˌəʊvəˈraɪd| verb:否决、使无效。

8virtual |ˈvɜːtʃʊəl| adj:虚拟的。


9subtract |səbˈtrækt| verb:减去。

10multiply |ˈmʌltɪplaɪ| verb:乘。

11divide |dɪˈvaɪd| verb:分、划分、分隔。

0
0
查看评论

《大话设计模式》之--第1章 代码无错就是优?----简单工厂模式

《大话设计模式》带给我一种全新的神奇的学习方式和思维,相比较GOF的《设计模式》而言,这本书更易于理解。鉴于目前网上的PDF大都是对本书拍照,而非文档,所以读起来很不清晰,也不能复制粘贴,因此本人决定整理并放到博客上,自己学习的同时能够方便大家。整理过程保证内容的一致性,根据本人的习惯可能会对某些语...
  • MONKEY_D_MENG
  • MONKEY_D_MENG
  • 2010-06-17 17:33
  • 3437

大话设计模式 第1章 代码无错就是优? 简单工厂模式

大话设计模式   第1章 代码无错就是优? ——简单工厂模式 所有代码C++实现 1.1问题描述: 请用C++、Java、C#或VB.NET任意一种面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果; //version 1.1 #include #...
  • u012605629
  • u012605629
  • 2014-12-11 15:21
  • 543

大话设计模式——第1章 代码无错就是优?——简单工厂模式

大话设计模式——第1章 代码无错就是优?——简单工厂模式 1.1  面试受挫 小菜今年计算机专业大四了,学了不少软件开发方面的东西,也学着编了些小程序,踌躇满志,一心要找一个好单位。当投递了无数份简历后,终于收到了一个单位的面试通知,小菜欣喜若狂。 到了人家单位,前台...
  • asdjy123
  • asdjy123
  • 2013-05-09 09:29
  • 869

代码无错就是优?----简单工厂模式

不识庐山真面目  只缘身在此山中    山重水复疑无路,柳暗花明又一村 简短 的两句诗 大概就可以概括我此刻学习的心情了吧!  开始大话设计模式这本书的第一章,时间并不长,但对于自己的写代码能力,真是得到了很深的认识,原来代码不是...
  • yudandan10
  • yudandan10
  • 2013-03-04 16:16
  • 2131

代码无错就是优?——简单工厂模式

简单工厂模式:从设计模式的类型上来说,
  • zwwtj2014
  • zwwtj2014
  • 2014-06-12 14:02
  • 386

《大话设计模式》——读后感 (1)代码无错就是优?——简单工厂模式

《大话设计模式》——读后感 (1)代码无错就是优?——简单工厂模式
  • chen_yao_kerr
  • chen_yao_kerr
  • 2017-07-04 14:27
  • 106

大话设计模式一:代码无错就是优----简单工厂模式

/* **计算机控制台程序 **要求体现面向对象的思想 */ #include #include using namespace std; //运算类(基类 抽象类) class Operation { public: Operation(double _numberA = 0.0, dou...
  • Tiramisu_zyp
  • Tiramisu_zyp
  • 2015-10-02 22:44
  • 261

读《大话设计模式》:代码无错就是优?

今天去图书馆借了本《大话设计模式》,看到第一个小故事"面试受挫",故事中的小菜在面试题目中"请用C++、Java、C#或VB.net任意一种面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果,"没有理会清楚,最终没有得到这个工作机会。看完...
  • guodun
  • guodun
  • 2009-02-17 08:57
  • 425

《大话设计模式》——读后感 (1)代码无错就是优?——简单工厂模式

《大话设计模式》
  • shuciqi
  • shuciqi
  • 2014-04-28 21:43
  • 949

《大话设计模式》学习第一章——代码无错就是优?简单工厂模式

110531 《大话设计模式》学习第一章——代码无错就是优?简单工厂模式 1.面向对象编程和活字印刷术的巧妙对比。 两者共有的特性:易维护、可复用、可扩展 活字印刷:修改,换字即可,易维护。 各个字可以在其它文章里使用,可复用。 文章要加字,加字即可,可扩展。 刻版印刷:要修改...
  • mozillafirefly
  • mozillafirefly
  • 2011-05-31 11:50
  • 254
    个人资料
    • 访问:92525次
    • 积分:2574
    • 等级:
    • 排名:第16771名
    • 原创:170篇
    • 转载:5篇
    • 译文:5篇
    • 评论:1条