抽象工厂模式

抽象工厂模式在工厂方法模式的基础上进行了改进,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

使用抽象工厂模式实现数据库切换例子如下:

首先定义两个对象的接口和它的多个具体的实现

    public interface IUser
    {
        void Insert(string name);
        IUser GetUser(int id);
    }

    public interface IDepartment
    {
        void Insert(string name);
        IDepartment GetDept(int id);
    }

    public class SQLServerUser : IUser
    {
        #region IUser 成员

        public void Insert(string name)
        {
            Console.WriteLine("Insert sqlserver user");
        }

        public IUser GetUser(int id)
        {
            Console.WriteLine("Get sqlserver user");
            return null;
        }

        #endregion
    }

    public class AccessUser : IUser
    {
        #region IUser 成员

        public void Insert(string name)
        {
            Console.WriteLine("Insert access user");
        }

        public IUser GetUser(int id)
        {
            Console.WriteLine("Get access user");
            return null;
        }

        #endregion
    }

    public class SQLServerDepartment : IDepartment
    {
        #region IDepartment 成员

        public void Insert(string name)
        {
            Console.WriteLine("Insert sqlserver department");
        }

        public IDepartment GetDept(int id)
        {
            Console.WriteLine("Get sqlserver department");
            return null;
        }

        #endregion
    }

    public class AccessDepartment : IDepartment
    {
        #region IDepartment 成员

        public void Insert(string name)
        {
            Console.WriteLine("Insert access department");
        }

        public IDepartment GetDept(int id)
        {
            Console.WriteLine("Get access department");
            return null;
        }

        #endregion
    }

 然后定义抽象工厂接口,和具体的工厂,具体的工厂负责创建一系列相关的对象

    public interface IFactory
    {
        IUser UserData();
        IDepartment DeptData();
    }

    public class SQLServerFactory : IFactory
    {
        #region IFactory 成员

        public IUser UserData()
        {
            return new SQLServerUser();
        }

        public IDepartment DeptData()
        {
            return new SQLServerDepartment();
        }

        #endregion
    }

    public class AccessFactory : IFactory
    {
        #region IFactory 成员

        public IUser UserData()
        {
            return new AccessUser();
        }

        public IDepartment DeptData()
        {
            return new AccessDepartment();
        }

        #endregion
    }

  客户端使用不同的工厂实例,完成一系列产品对象的创建

            //实例化Sqlserver数据库访问对象
            //IFactory factory = new SQLServerFactory();

            //实例化Access数据库访问对象, 两个工厂对象二选一
            IFactory factory = new AccessFactory();

            IUser userData = factory.UserData();
            userData.Insert("test");
            userData.GetUser(1);


            IDepartment deptData = factory.DeptData();
            deptData.Insert("test");
            deptData.GetDept(1);

  

抽象工厂方法的优点是便于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,所以改变一个应用的具体工厂变得非常容易,只需要改变具体工厂即可。

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

但是抽象工厂方法在需要初始化很多次的时候则是不便使用的,这是则可以使用简单工厂加配置和反射。

下面将抽象工厂改为简单工厂加配置和反射完成

     /// <summary>
    /// 简单工厂模式结合反射,使用反射避免了switch case 的判断
    /// </summary>
    public class SimplyFactory
    {
        private static string assemblyName = "AbstractFactoryModel";
        //该字符串可以使用配置文件
        private static string dbType = "SQLServer";

        public IUser UserData()
        {
            IUser userData = (IUser)Assembly.Load(assemblyName).CreateInstance(assemblyName + "." + dbType + "User");
            return userData;
        }

        public IDepartment DeptData()
        {
            IDepartment deptData = (IDepartment)Assembly.Load(assemblyName).CreateInstance(assemblyName + "." + dbType + "Department");
            return deptData;
        }
    }

 在需要更改实例化的对象时,不需要修改代码,而只需要修改配置文件即可,客户端的使用如下:

            //实例化时无需制定任何类型,全部由工厂根据配置实现
            SimplyFactory factory = new SimplyFactory();
            IUser userData = factory.UserData();
            IDepartment deptData = factory.DeptData();

            userData.Insert("test");
            userData.GetUser(1);

            deptData.Insert("test");
            deptData.GetDept(1);

 这样,客户端在需要实例化多个工厂的时候,只需要修改配置文件,不需要修改每一个实例化代码。

 

posted @ 2016-04-22 16:55  angela217  阅读(186)  评论(0编辑  收藏  举报