zoukankan      html  css  js  c++  java
  • 抽象工厂模式

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

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

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

        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);
    

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

  • 相关阅读:
    mysql存储过程详细教程
    js timestamp与datetime之间的相互转换
    spring集成httpclient配置
    Spring使用@scope("session")爆org.springframework.beans.factory.UnsatisfiedDependencyException
    算术编码Arithmetic Coding-高质量代码实现详解
    String Reduction
    (转)Maximum subarray problem--Kadane’s Algorithm
    判断一个字符串在至多删除k个字符后是否为回文串
    最小区间使得至少包含每组元素中的一个
    Pots of gold game:看谁拿的钱多
  • 原文地址:https://www.cnblogs.com/angela217/p/5421977.html
Copyright © 2011-2022 走看看