简单工厂模式

  从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

  实现方式

  简单工厂的UML类图

   

  简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

  简单工厂模式中包含的角色及其相应的职责如下:

   工厂角色(Creator):这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。当然工厂类必须能够被外界调用,创建所需要的产品对象。 

   抽象(Product)产品角色:简单工厂模式所创建的所有对象的父类,注意,这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口。

  具体产品(Concrete Product)角色:简单工厂所创建的具体实例对象,这些具体的产品往往都拥有共同的父类。

  简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程,所有变化都封装在工厂类,Client端不用关心类的实例化。

  下面通过一个简单的实例说明简单工厂:

  Window系统自带的计算器,包括了加,减,乘,除等多种运算操作与演示,然而不管运算方式有多少种(相当于有多少种产品),但最终得到的还是调用该运算方式的运算结果,这个过程其实就是接收运算参数,与运算符号,得到运算结果。可以创建一个运算父类与工厂类,各种运算方式为运算子类,通过输入不同的运算符号,工厂类就实例化出合适的运算对象,然后通过多态,返回父类的方式,从而实现了计算器的结果。

  此实例简单的UML图

    

   代码:

   

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OperationLibrary
{
    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; }
        }


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

    }

    /// <summary>
    /// 加法类
    /// </summary>
    class OperationAdd : 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;
        }
 
    }

    /// <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 OperationSqr : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberB * NumberB;
            return result;
        }
    }

    /// <summary>
    /// 平方根类
    /// </summary>
    class OperationSqrt : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            if (NumberB < 0)
                throw new Exception("负数不能开平方根。");
            result = Math.Sqrt(NumberB);
            return result;
        }
    }

    /// <summary>
    /// 相反数类
    /// </summary>
    class OperationReverse : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = -NumberB;
            return result;
        }
    }

}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OperationLibrary
{
    /// <summary>
    /// 运算工厂类
    /// </summary>
    public class OperationFactory
    {
        public static Operation CreateOperation(string OperationName)
        {
            Operation oper = null;
            switch (OperationName)
            {
                case "+":
                    {
                        oper = new OperationAdd();
                        break;
                    }
                case "-":
                    {
                        oper = new OperationSub();
                        break;
                    }
                case "*":
                    {
                        oper = new OperationMul();
                        break;
                    }

                case "/":
                    {
                        oper = new OperationDiv();
                        break;
                    }
                case "sqr":
                    {
                        oper = new OperationSqr();
                        break;
                    }
                case "sqrt":
                    {
                        oper = new OperationSqrt();
                        break;
                    }
                case "+/-":
                    {
                        oper = new OperationReverse();
                        break;
                    }
            }
            return oper;
        }
    }
}

 

Client调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OperationLibrary;

namespace 计算器控制台程序
{
    class Program
    {
        static void Main(string[] args)
        {
            Operation oper = null;
            double NumberA = 10.0;
            double NumberB = 2.0;
            string Operationtype="+";

            //通过工厂类实例化对象
            oper = OperationFactory.CreateOperation(Operationtype);

            //传递运算参数
            oper.NumberA = NumberA;
            oper.NumberB = NumberB;


            string result = oper.GetResult().ToString();

           //运算结果
            Console.WriteLine("运算结果={0}", result);
            Console.Read();

        }
    }
}

 


 

简单工厂模式的优缺点分析: 

       优点:工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。

      缺点:由于工厂类集中了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会受到牵连;而且由于简单工厂模式的产品室基于一个共同的抽象类或者接口,这样一来,但产品的种类增加的时候,即有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建何种种类的产品,这就和创建何种种类产品的产品相互混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。而且更重要的是,简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,因为当我新增加一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。

      总结一下:简单工厂模式分离产品的创建者和消费者,有利于软件系统结构的优化;但是由于一切逻辑都集中在一个工厂类中,导致了没有很高的内聚性,同时也违背了“开放封闭原则”。另外,简单工厂模式的方法一般都是静态的,而静态工厂方法是无法让子类继承的,因此,简单工厂模式无法形成基于基类的继承树结构。

    

  

 

 

posted @ 2012-11-27 11:27  火與劍  阅读(428)  评论(0编辑  收藏  举报