您的位置:首页 > 其它

设计模式之工厂家族

2015-12-13 18:29 330 查看
工厂家族是指创建型模式中的三个名称很相像的模式,即简单工厂、工厂方法和抽象工厂模式,鼎鼎大名的工厂家族使我们编写代码更加简练,更加容易维护、扩展和复用,虽然工厂家族们有其各自的优点,但同时局限性也是不可避免的,下面对三工厂进行一个简单的总结。

一、简单工厂模式

简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,其实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。主要是解决如何去实例化对象的问题,下面以实现计算器功能为例:




namespace 简单工厂模式
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.Write("请输入数字A:");
                int strNumberA = Convert.ToInt32(Console.ReadLine());  //隐式转换
                Console.Write("请选择运算符号(+、-、*、/)");
                string stroperate = Console.ReadLine();
                Console.Write("请输入数字B");
                int strNumberB = Convert.ToInt32(Console.ReadLine());
                Operation oper;
                oper = OperationFactory.createOperate("strOperation");  //获取运算符
                oper.NumberA = strNumberA;  //NumberA赋值
                oper.NumberB = strNumberB;  //NumberB赋值
                double result = oper.GetResult();  //数值计算,获得结果
                Console.WriteLine(result);
            }
            catch (Exception ex)
            {
                Console.WriteLine("您的输入有错:" + ex.Message);
            }
        }
    }
    //简单运算工厂类
    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运算类
    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()  //继承父类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;
        }
    }

优点:工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。

缺点:简单工厂严格来说并不算一种设计模式,因为它违反了开放-封闭原则,简单工厂是通过分支来判断选择实例化哪一个类,如果需求更改,那么就要更改工厂类了,不仅对扩展开放了,对修改也开放了。

二、工厂方法模式

工厂方法模式主要针对的是开放-封闭原则,它定义一个用于创建对象的借口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。也就是说,在子类中去实例化对象,让子类做到需要什么就实例化什么。还以计算器为例:



关键代码:

//工厂借口
    interface IFactory
    {
        Operation CreateOperation();
    }
//具体工厂类(减法、乘法、除法同加法类)
    class AddFactory : IFactory  //加法类工厂
    {
        public Operation CreateOperation()
        {
            return new OperationAdd();
        }
    }
//客户端实现
            IFactory operFactory = new AddFactory();  //实例化加法类工厂
            Operation oper=operFactory.CreateOperation ();  //实例化加法运算类
            oper.NumberA = 1;
            oper.NumberB = 2;
            double result = oper.GetResult();
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,也就是说将简单工厂的内部逻辑判断移到了客户端代码来进行,那么如果增加算法的话,虽然不用去改工厂类的case分支,但是需要到客户端去修改了。

工厂方法模式式简单工厂模式的进一步抽象和推广,由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。但缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。

三、抽象工厂模式

抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。以数据访问程序为例,如果数据库中只有一个User表,那么使用简单工厂模式,定义一个IUser接口和访问IUser的工厂接口就可以实现了,但如果再增加一个Department表,那么就要用抽象工厂模式了,在工厂接口中增加接口方法,也要在工厂类中增加实例化方法。



关键代码:

//SqlserverDepartment类,用于访问SQL Server的Department
    class sqlserverDepartment : IDepartment
    {
        public void Insert(Department department)
        {
            Console.WriteLine ("在SQL Server中给Department表增加一条记录");
        }
        public Department GetDepartment(int id)
        {
            Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
            return null;
        }
    }
    //IFactory接口,定义一个创建访问Department表对象的抽象的工厂接口
    interface IFactory
    {
        IUser CreateUser();
        IDepartment CreateDepartment();  //增加的接口方法
    }
    //SQLServerFactory类,实现IFactory接口,实例化SQLserverUser和SQLserverDepartment
    class SqlServerFactory : IFactory
    {
        public IUser CreateUser()
        {
            return new SqlserverUser();
        }
        public IDepartment CreateDepartment()  //增加了SQLserverDepartment工厂
        {
            return new sqlserverDepartment();
        }
    }
优点

1、易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。

2、让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。


缺点:


产品扩展非常困难,由于抽象工厂模式解决的是涉及到多个产品系列的问题,那么再进行产品扩展需要进行大批量的改动,所以有时候也要工厂家族的其他族员和反射等方法来对其改进。

小结

工厂家族虽然给编程带来了很多好处,各有其优点,但他们也各有其局限性,都不够灵活,设计模式的使用不是一成不变必须按套路来的,需要我们在实际情况中配合使用,从而做到面向对象,编程是门艺术,随着学习的不断深入,相信我们一定会达到炉火纯青,随手写出优美代码的程度的,fighting!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: