zoukankan      html  css  js  c++  java
  • 小猪学设计模式——工厂模式之简单工厂(静态工厂)

    前言

    在我们写代码过程中,经常使用类似这样的代码

    ClassA a = new ClassA();

    严格意义上来讲这段代码已经依赖具体的实现了。当使用"new"关键字创建一个对象时,此时该类就依赖与这个对象,也就是他们之间的耦合度高,当需求变化时,我们就不得不去修改此类的源码。这违反了编程的原则里的“依赖抽象”“开放—关闭”等等一系列原则。

    简单工厂

    此时我们可以运用面向对象(OO)的很重要的原则去解决这一的问题,该原则就是——封装改变。

    针对接口编程,可以隔离掉以后系统可能发生的一大堆改变。入股代码是针对接口而写,那么可以通过多态,它可以与任何新类实现该接口。但是,当代码使用一大堆的具体类时,等于是自找麻烦,因为一旦加入新的具体类,就必须要改变代码。在这里我们希望能够调用一个简单的方法,我传递一个参数过去,就可以返回给我一个相应的具体对象。

    定义

    简单工厂模式又称之为静态工厂方法,属于创建型模式。在简单工厂模式中,可以根据传递的参数不同,返回不同类的实例。简单工厂模式定义了一个类,这个类专门用于创建其他类的实例,这些被创建的类都有一个共同的父类。

    分析分析

           Factory:工厂角色。专门用于创建实例类的工厂,提供一个方法,该方法根据传递的参数不同返回不同类的具体实例。
           Product:抽象产品角色。为所有产品的父类。
           ConcreteProduct:具体的产品角色。

    简单工厂模式将对象的创建和对象本身业务处理分离了,可以降低系统的耦合度,使得两者修改起来都相对容易些。当以后实现改变时,只需要修改工厂类即可。

    下面以计算器的例子来说明简单工厂方法

    基类:操作符(product)

    public class Operation
    {
        private double _numberA = 0;
        private double _numberB = 0;
     
        /// <summary>
        /// 数字A
        /// </summary>
        public double NumberA
        {
            get
            {
                return _numberA;
            }
            set
            {
                _numberA = value;
            }
        }
     
        /// <summary>
        /// 数字B
        /// </summary>
        public double NumberB
        {
            get
            {
                return _numberB;
            }
            set
            {
                _numberB = value;
            }
        }
     
        /// <summary>
        /// 得到运算结果
        /// </summary>
        /// <returns></returns>
        public virtual double GetResult()
        {
            double result = 0;
            return result;
        }
     
        /// <summary>
        /// 检查输入的字符串是否准确
        /// </summary>
        /// <param name="currentNumber"></param>
        /// <param name="inputString"></param>
        /// <returns></returns>
        public static string checkNumberInput(string currentNumber, string inputString)
        {
            string result = "";
            if (inputString == ".")
            {
                if (currentNumber.IndexOf(".") < 0)
                {
                    if (currentNumber.Length == 0)
                        result = "0" + inputString;
                    else
                        result = currentNumber + inputString;
                }
            }
            else if (currentNumber == "0")
            {
                result = inputString;
            }
            else
            {
                result = currentNumber + inputString;
            }
     
            return result;
        }
    }

    具体操作(加减乘除)类:(ConcreteProduct)

    /// <summary>
    /// 加法类
    /// </summary>
    class OperationAdd : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA + NumberB;
            return result;
        }
    }
     
    /// <summary>
    /// 减法类
    /// </summary>
    class OperationSub : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA - NumberB;
            return result;
        }
    }
     
    /// <summary>
    /// 乘法类
    /// </summary>
    class OperationMul : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA * NumberB;
            return result;
        }
    }
     
    /// <summary>
    /// 除法类
    /// </summary>
    class OperationDiv : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            if (NumberB == 0)
                throw new Exception("除数不能为0。");
            result = NumberA / NumberB;
            return result;
        }
    }

    运算工厂类:(Factory)

        /// <summary>
        /// 运算类工厂
        /// </summary>
    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;
        }
    }

    这样就创建了简单工厂里面的三个角色、

    然后在客户端需要具体操作时使用下列代码:

    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 oper;
            oper = OperationFactory.createOperate(strOperate);
            oper.NumberA = Convert.ToDouble(strNumberA);
            oper.NumberB = Convert.ToDouble(strNumberB);
            strResult = oper.GetResult().ToString();
     
            Console.WriteLine("结果是:" + strResult);
     
            Console.ReadLine();
     
     
        }
        catch (Exception ex)
        {
            Console.WriteLine("您的输入有错:" + ex.Message);
        }
    }

    优点
               1、简单工厂模式实现了对责任的分割,提供了专门的工厂类用于创建对象。
               2、客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
               3、通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

    缺点
               1、由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
               2、使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
               3、系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
               4、简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
    五、简单工厂模式的使用场景                                                                                        
               1、  工厂类负责创建的对象比较少。
               2、  客户端只知道传入工厂类的参数,对于如何创建对象不关心。

    六、总结                                                                                                                    
            1、  简单工厂模式的要点就在于当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
            2、  简单工厂模式最大的优点在于实现对象的创建和对象的使用分离,但是如果产品过多时,会导致工厂代码非常复杂。

  • 相关阅读:
    Vue项目中跨域问题解决
    子网掩码
    C++的const类成员函数
    在python3中使用urllib.request编写简单的网络爬虫
    Linux 重定向输出到多个文件中
    背包问题
    hdu-1272 小希的迷宫
    SQLAlchemy 几种查询方式总结
    pycharm快捷键、常用设置、配置管理
    python3判断字典、列表、元组为空以及字典是否存在某个key的方法
  • 原文地址:https://www.cnblogs.com/smallerpig/p/3646148.html
Copyright © 2011-2022 走看看