简单工厂、工厂方法、抽象工厂模式

简单工厂、工厂方法和抽象工厂这三种设计模式都和工厂有关,准确的来说都和对象的创建有关。它们之间有什么区别呢?我认为就是一个逐步改进的过程。

简单工厂

不论创建哪个对象,都封装在一个简单工厂类中,一对多
这里写图片描述
优点:将客户端与对象的创建(选择创建哪个对象)分离,去除了客户端对具体产品的依赖
缺点:违背了开闭原则,增加新的类就需要修改简单工厂类,而不是可扩展

工厂方法

将创建对象的工厂抽象出来,为每一个需要实例化的类都开辟一个具体的工厂类,一对一
这里写图片描述
优点:既解决了简单工厂违背了开闭原则的缺点,但是每增加一个产品,就要增加一个具体的产品工厂类,又保持了实例化对象封装的特点
缺点:将判断(创建哪个对象)移到了客户端,更改要实例化的对象时需要修改客户端

抽象工厂

这里写图片描述
  优点:①易于交换系列产品 ②让具体的创建实例过程和客户端分离,客户端是通过抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在代码中。遵循了开闭原则和依赖倒置原则。
  缺点:如果要增加产品,需要修改抽象工厂类和具体工厂类
  适用情况:解决涉及到多个产品系列的问题,用于系列产品之间的交换,比如访问不同的数据库
  改进:用【简单工厂+反射】改进抽象工厂,去除抽象工厂类和具体工厂类

简单工厂和工厂方法的区别

①工厂方法和简单工厂比较,将工厂类也抽象出来,有接口工厂和具体工厂
②工厂方法运用了依赖倒置原则,针对接口编程而不是针对实现编程
③简单工厂在程序编译时就已经确定了实例化哪个对象,而工厂方法将程序编译时转为运行时,由于客户端运用的是接口工厂,所以在运行时才知道具体实例化运行哪一个对象。
 具体看下图:
 1)简单工厂
这里写图片描述
 2)工厂方法
这里写图片描述

工厂方法和抽象工厂

我认为工厂方法和抽象工厂基本上没有什么区别,只是增加了多个系列类而已,而且工厂类中创建对象的方法也增多了。

利用反射改进抽象工厂

对抽象工厂的进一步改进,可以用一个简单工厂类替换掉抽象工厂类和具体工厂类,不过在简单工厂类中不再用 switch 语句选择创建对象,而是利用反射技术。
反射技术的格式为:

Assembly.Load("程序集名称").CreateInstance("命名空间.类名")

使用示例:

//使用之前需要先引用
using System.Reflection;
using System.Configuration;

namespace _04抽象工厂模式
{
    class DataAccess
    {  
        //程序集名称
        private static readonly string AssemblyName = "04抽象工厂模式";
        private static readonly string db = "Sqlserver";

        public static IUser CreateUser()
        {
            //命名空间.类名
            string className = "_" + AssemblyName + "." + db + "User";
            return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
        }
        public static IDepartment CreateDepartment()
        {
            string className = "_" + AssemblyName + "." + db + "Department";
            return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
        }
    }
}

注意:
①一个项目就是一个程序集,准确的说程序集就是编译后的.exe文件或.dll文件,但程序集名称可以和项目名称不同,可以右键项目属性查看程序集名称。
②命名空间:

namespace _04抽象工厂模式     //这就是命名空间的名称

一个项目可以有不同的命名空间,但是一般都用相同的命名空间。
③所有在用简单工厂的地方,都可以用反射技术来去除 switch。

猜你喜欢

转载自blog.csdn.net/zwj_jyzl/article/details/80952757
今日推荐