4. 抽象工厂模式(Abstract Factory Pattern)

 

抽象工厂模式(初版)

1、介绍
    怎么理解抽象工厂模式呢?这篇的介绍我拖了好久,后面发现抽象工厂其实就是工厂方法模式的更一般化,也符合了抽象化即一般化的事物发展规律。单个产品的实现用工厂方法模式,多个产品的实现就需要横向扩展,扩展后就变为抽象工厂模式了。
2、UML 图

3、优缺点

优势:满足开放封闭原则(OCP)、依赖倒置原则(DIP)
劣势:简简单单的一个功能却加的类太多了,那有没有改进的可能呢?答案是有的,见抽象工厂模式(改版1)

4、代码附录

实体类:
public class User
    {
        private int _id;
        public int Id
        {
            get { return this._id; }
            set { this._id = value; }
        }

        private string _name;
        public string Name
        {
            get { return this._name; }
            set { this._name = value; }
        }
    }
    public class Department
    {
        private int _id;
        public int Id
        {
            get { return this._id; }
            set { this._id = value; }
        }

        private string _name;
        public string Name
        {
            get { return this._name; }
            set { this._name = value; }
        }
    }

 

IFactory 接口及实现:
    public interface IFactory
    {
        IUser CreateUser();

        IDepartment CreateDepartment();
    }
 public class SqlServerFactory:IFactory
    {
        public IUser CreateUser()
        {
            return new SqlServerUser();
        }

        public IDepartment CreateDepartment()
        {
            return new SqlDepartment();
        }
    }
public class AccessFactory:IFactory
    {
        public IUser CreateUser()
        {
            return new AccessUser();
        }

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

 

IUser、IDepartment 接口及对应的实现
public interface IUser
    {
        void Insert(User user);

        User GetEntity(int id);
    }
    public class SqlServerUser:IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("我这里用SqlServer插入一条User");
        }

        public Entity.User GetEntity(int id)
        {
            Console.WriteLine("我这里用SqlServer获取一条User");
            return null;
        }
    }
    public class AccessUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("我这里用Access插入一条User");
        }

        public Entity.User GetEntity(int id)
        {
            Console.WriteLine("我这里用Access获取一条User");
            return null;
        }
    }
    public interface  IDepartment
    {
        void Insert(Department dp);

        Department GetEntity(int id);
    }
    public class SqlDepartment : IDepartment
    {
        public void Insert(Department dp)
        {
            Console.WriteLine("我这里用SqlServer插入一条Department");
        }

        public Entity.Department GetEntity(int id)
        {
            Console.WriteLine("我这里用SqlServer获取一条Department");
            return null;
        }
    }
    public class AccessDepartment : IDepartment
    {
        public void Insert(Department dp)
        {
            Console.WriteLine("我这里用Access插入一条Department");
        }

        public Entity.Department GetEntity(int id)
        {
            Console.WriteLine("我这里用Access获取一条Department");
            return null;
        }
    }

 

应用:

            var user = new User();
            IFactory factory=new AccessFactory();
            var us = factory.CreateUser();
            us.Insert(user);
            us.GetEntity(1);

            Console.ReadLine();

 

 

抽象工厂模式(改版1)

    1. 介绍
        上面我们看到实现一个抽象工厂模式,要建大量的类,的确有些繁琐;那么哪些类可以去掉呢,我们试着去掉 IFactory、SqlServerFactory、AccessFactory ;取而代之的是DataAccess 用简单工厂模式 实现。
    2. UML图


    3. 优缺点
    优势:类个数减少的同事,使用者完全不用考虑该功能是用哪种数据库实现的。
    劣势:DataAccess中多个switch逻辑不好
    4. 附录
DataAccess 类:
    public class DataAccess
    {
        private static string dbString = @"Access";

        public static IUser CreateUser()
        {
            switch (dbString)
            {
                case "SqlServer":
                    return  new SqlServerUser();
                case "Access":
                   return new AccessUser();
                default:
                    return null;
            }
        }

        public static IDepartment CreateDepartment()
        {
            switch (dbString)
            {
                case "SqlServer":
                    return new SqlServerDepartment();
                case "Access":
                    return new AccessDepartment();
                default:
                    return null;
            }
        }
    }

 

Entity 类:
    public class User
    {
        private int _id;
        public int Id
        {
            get { return this._id; }
            set { this._id = value; }
        }
 
        private string _name;
        public string Name
        {
            get { return this._name; }
            set { this._name = value; }
        }
    }
    public class Department
    {
        private int _id;
        public int Id
        {
            get { return this._id; }
            set { this._id = value; }
        }
 
        private string _name;
        public string Name
        {
            get { return this._name; }
            set { this._name = value; }
        }
    }

 

IUser、IDepartment 接口及对应的实现:
    public interface IUser
    {
        void Insert(User user);
        User GetEntity(int id);
    }
    public class SqlServerUser:IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("我这里用SqlServer插入一条User");
        }
        public Entity.User GetEntity(int id)
        {
            Console.WriteLine("我这里用SqlServer获取一条User");
            return null;
        }
    }
    public class AccessUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("我这里用Access插入一条User");
        }
        public Entity.User GetEntity(int id)
        {
            Console.WriteLine("我这里用Access获取一条User");
            return null;
        }
    }
    public interface  IDepartment
    {
        void Insert(Department dp);
        Department GetEntity(int id);
    }
    public class SqlDepartment : IDepartment
    {
        public void Insert(Department dp)
        {
            Console.WriteLine("我这里用SqlServer插入一条Department");
        }
        public Entity.Department GetEntity(int id)
        {
            Console.WriteLine("我这里用SqlServer获取一条Department");
            return null;
        }
    }
    public class AccessDepartment : IDepartment
    {
        public void Insert(Department dp)
        {
            Console.WriteLine("我这里用Access插入一条Department");
        }
        public Entity.Department GetEntity(int id)
        {
            Console.WriteLine("我这里用Access获取一条Department");
            return null;
        }
    }

 

应用:

            User user=new User();
            Department dp = new Department();

            IUser iu = DataAccess.CreateUser();
            IDepartment idp = DataAccess.CreateDepartment();

            iu.Insert(user);
            iu.GetEntity(1);

            idp.Insert(dp);
            idp.GetEntity(1);

 

抽象工厂模式(改版2)

    1. 介绍
        改版1中,我们看到 switch 是一个很讨厌的玩意儿,代码重复不说,还逻辑冗余,接下来我们利用反射解决这一块。
    2. 优缺点
        很明显,通过反射代码简洁了很多
    3. 附录代码
    public class DataAccess
    {
        private static string assemblyName = "Abstract.Pattern.v1";
        private static string dbString = @"Access";

        public static IUser CreateUser()
        {
            string className = assemblyName + "." + dbString + "User";
            return (IUser)Assembly.Load(assemblyName).CreateInstance(className);
        }

        public static IDepartment CreateDepartment()
        {
            string className = assemblyName + "." + dbString + "Department";
            return (IDepartment)Assembly.Load(assemblyName).CreateInstance(className);
        }
    }

 

抽象工厂模式与工厂方法模式的区别

工厂方法模式 抽象工厂模式
1. 针对的是单一的产品结构 1. 针对的是多个产品结构
2. 一个抽象的产品类 2. 多个抽象的产品类
 
 
 
 
 
 
 
 
posted @ 2019-05-01 07:54  NCat  阅读(86)  评论(0)    收藏  举报