简单工厂设计模式(计算器实例优化)

简单工厂设计模式(计算器实例优化)

介绍

本文内容引用自《大话这设计模式》这本书第一章节简单工厂设计模式,供自己提高代码水平使用。

案例也同样采用计算器功能实现方式展开

实现功能---->封装---->继承---->多态---->面向对象

为什么采用面向对象编程而不是面向过程呢?

在当今互联网开发的大型企业中你会发现,当你接到一个功能模块的时候不会给你完整的项目源码,特别是核心的东西,为什么呢?

仔细想一下,如果公司把员工薪资分发系统让你修改,这时你动了一下坏心思,做了一层 If 判断,如果名字是自己的话薪资*2,是不是公司就赔了?况且公司也不会这么傻,把这种核心的功能让新手做修改,这就引入代码的面向对象,将代码分为逻辑层和业务层分开处理,这样不仅逻辑清晰方便后期的修改,也方便了公司为自身的保护。

实例讲解

我们创建一个主控制台,先用一个面向过程的编程方式去写一个计算器功能,代码如下

csharp 复制代码
while (true)
            {
                try
                {
                    Console.WriteLine("请输入第一个数字一");
                    double number1 = double.Parse(Console.ReadLine());
                    Console.WriteLine("请输入运算符");
                    string symbol = Console.ReadLine();
                    Console.WriteLine("请输入第一个数字二");
                    double number2 = double.Parse(Console.ReadLine());
                    switch (symbol)
                    {
                        case "+":
                            Console.WriteLine(number1 + number2);
                            break;
                        case "-":
                            Console.WriteLine(number1 - number2);
                            break;
                        case "*":
                            Console.WriteLine(number1 * number2);
                            break;
                        case "/":
                            if (number2 == 0d)
                            {
                                Console.WriteLine("被除数不能为0");
                                break;
                            }
                            Console.WriteLine(number1 / number2);
                            break;
                        default:
                            break;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }

这时候我们分析一下

  1. 首先逻辑是没有问题的,如果后期修改怎么办?是否需要将完整的代码拿出来修改?
  2. 如果我们后期需要增加一个开平方根,时候会影响了其他运算的逻辑?
  3. 如果我们现在需要开发另外一个平台的计算器功能,我们能都将这个代码拿过去直接复用?

先回答第一个问题,这个代码比较简单,修改起来也比较方便,但是如果项目需求比较大,我们可能会话费很长时间去找当时写的代码,这时候会非常话费时间,那么我们可以将逻辑层和业务层分开,代码如下

业务层划分出来

csharp 复制代码
public class Operation
    {

        public static double GetResult(double number1,double number2,string symbol) 
        {
            double result = 0;
            switch (symbol)
            {
                case "+":
                    result = number1 + number2;
                    break;
                case "-":
                    result = number1 - number2;
                    break;
                case "*":
                    result = number1 * number2;
                    break;
                case "/":
                    if (number2 == 0d)
                    {
                        Console.WriteLine("被除数不能为0");
                        break;
                    }
                    result = number1 / number2;
                    break;
                default:
                    break;
            }
            return result;
        }
    }

逻辑层

csharp 复制代码
while (true)
            {
                try
                {
                    Console.WriteLine("请输入第一个数字一");
                    double number1 = double.Parse(Console.ReadLine());
                    Console.WriteLine("请输入运算符");
                    string symbol = Console.ReadLine();
                    Console.WriteLine("请输入第一个数字二");
                    double number2 = double.Parse(Console.ReadLine());

                    double result = Operation.GetResult(number1,number2,symbol);
                    Console.WriteLine("结果为"+result);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }

这时候是否显得比较整洁,之后修改的时候我们直接使用Operation这个脚本修改即可

回答第二个问题

如果这时候我们需要增加一个需求,当我们做➕法运算的时候,我们得到的值始终是要多➕2的,这时候我们如果按照当前的方法修改的话,我们需要改动Operation这个类中的GetResult方法即可,但是这个方法里面包含了4个逻辑算式,如果这时候不小心动了其他的怎么办?所以这时候我们就要引入面向对象知识,封装,继承,多态的方式去修改当前代码。代码如下

csharp 复制代码
public class Operation
    {

        private double m_number1;

        private double m_number2;

        public double Number1 { get { return m_number1; } set { m_number1 = value; } }

        public double Number2 { get { return m_number2; } set { m_number2 = value; } }


        public virtual double GetResult() 
        {
            double result = 0;
            return result;
        }
    }

    public class Add : Operation 
    {
        public override double GetResult()
        {
            double result = Number1 + Number2;
            return result;
        }
    }

    public class Subtract : Operation
    {
        public override double GetResult()
        {
            double result = Number1 - Number2;
            return result;
        }
    }

    public class Multiply : Operation
    {
        public override double GetResult()
        {
            double result = Number1 * Number2;
            return result;
        }
    }

    public class Divide : Operation
    {
        public override double GetResult()
        {
            if(Number2 == 0)
                throw new Exception("除数不能为0");
            double result = Number1 / Number2;
            return result;
        }
    }

继承

修改业务层层,增加两个属性,并且重写一个方法,在定义四个不同的运算符类,分别继承业务层Operation,根据不同的方式重写基类方法

这里回答第三个问题

如何复用我们当前写的东西呢?这里可能对于刚开始编程的人来说不会区分对象,这里我们将每一个运算式分别定义一个对象,然后这里的每一个对象分别有两个属性,数字一和数字二,这样理解就比较清晰,既然明白了对象,我们就将面向对象的多态简单工厂设计模式引入到里面,从而达到我们所写代码的复用性,代码如下:

简单工厂:(多态)

csharp 复制代码
public static Operation CreateOperation(string symbol) 
        {
            Operation oper = null;
            switch (symbol)
            {
                case "+":
                    oper = new Add();
                    break;
                case "-":
                    oper = new Subtract();
                    break;
                case "*":
                    oper = new Multiply();
                    break;
                case "/":
                    oper = new Divide();
                    break;
                default:
                    break;
            }
            return oper;
        }

业务层:(解耦合)

csharp 复制代码
public class Operation
    {

        private double m_number1;

        private double m_number2;

        public double Number1 { get { return m_number1; } set { m_number1 = value; } }

        public double Number2 { get { return m_number2; } set { m_number2 = value; } }


        public virtual double GetResult() 
        {
            double result = 0;
            return result;
        }
    }

    public class Add : Operation 
    {
        public override double GetResult()
        {
            double result = Number1 + Number2;
            return result;
        }
    }

    public class Subtract : Operation
    {
        public override double GetResult()
        {
            double result = Number1 - Number2;
            return result;
        }
    }

    public class Multiply : Operation
    {
        public override double GetResult()
        {
            double result = Number1 * Number2;
            return result;
        }
    }

    public class Divide : Operation
    {
        public override double GetResult()
        {
            if(Number2 == 0)
                throw new Exception("除数不能为0");
            double result = Number1 / Number2;
            return result;
        }
    }

主控制台

csharp 复制代码
class Program
    {
        static void Main(string[] args)
        {

            while (true)
            {
                try
                {
                    Console.WriteLine("请输入第一个数字一");
                    double number1 = double.Parse(Console.ReadLine());
                    Console.WriteLine("请输入运算符");
                    string symbol = Console.ReadLine();
                    Console.WriteLine("请输入第一个数字二");
                    double number2 = double.Parse(Console.ReadLine());

                    Operation oper;
                    oper = OperationFactory.CreateOperation(symbol);
                    oper.Number1 = number1;
                    oper.Number2 = number2;
                    Console.WriteLine("结果为"+oper.GetResult());
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }
    }

总结

巧妙的使用面向对象的封装继承和多态会让我们后期的维护节约不少时间,提高了开发的效率,当我们将代码移植到别的平台的时候,我们只需要将业务层Operation 和 OperationFactory移植即可方便调用。

相关推荐
ZSYP-S6 分钟前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos9 分钟前
c++------------------函数
开发语言·c++
越甲八千11 分钟前
重温设计模式--享元模式
设计模式·享元模式
程序员_三木21 分钟前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
是小崔啊31 分钟前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama37 分钟前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全40 分钟前
Java的基础概念(一)
java·开发语言·python
liwulin050641 分钟前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr
jackiendsc1 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
Oneforlove_twoforjob1 小时前
【Java基础面试题027】Java的StringBuilder是怎么实现的?
java·开发语言