C#设计模式之抽象工厂模式

前言

抽象工厂模式,简单工厂(点我呀~)工厂方法模式(点我呀)。这三个概念的掌握以及区别。

抽象工厂模式

英文:Abstract Factory

what

提供一个创建一系列相关或依赖对象的接口,而无需指定它们具体的类。

结构图

抽象工厂
IFactory
是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。

concretefactory1
是具体的工厂,,为创建不同的产品对象,客户端应使用不同的具体工厂。

情景走向

  1. 基本的数据访问程序:sqlserverUser se = new sqlserveruser()使得se这个对象被框死在SQLserver上。如何将这个改变成灵活的,多态的?
  2. 使用工厂方法模式的数据访问程序:结构图如下,增加接口和工厂
    定义一个用于创建对象的接口,让子类决定实例化哪一类。
    1

  3. 抽象工厂模式的数据访问程序,结构图如下,增加具体部门表的处理。
    IDepartment接口,用户客户端访问,解除与具体数据库访问的耦合。

2
4. 反射+抽象工厂的数据访问程序
5. 反射+配置文件实现数据访问程序

优缺点

优点:
1. 易于交换产品系列。由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同 产品配置。
2. 它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
3. 良好运用了开放-封闭原则依赖倒转原则

缺点:
增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开放-封闭原则”的支持呈现倾斜性

代码展示

用户类:

 //用户类
    class User  
    {
        private int _id;
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }

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

    //sqlserverUser类,用于访问sql的user

    class sqlserverUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在sql中给User表添加一条记录");
        }

        public User GetUser(int id)
        {
            Console.WriteLine("在sql中根据ID得到user表一条记录");
            return null;
        }
    }

    //AccessUser类,用于访问access的user,同上↑

    class AccessUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在access中给User表添加一条记录");
        }

        public User GetUser(int id)
        {
            Console.WriteLine("在access中根据ID得到user表一条记录");
            return null;
        }
    }

用户接口:

interface IUser  //接口
    {
        void Insert(User user);
        User GetUser(int id);
    }

抽象工厂接口:

//定义一个创建访问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();
        }
    }

    //AccessFactory类,实现IFactory接口,实例化AccessUser和AccessDepartment

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

        public IDepartment CreateDepartment()  //增加了sqlserverdepartment工厂
        {
            return new AccessDepartment();
        }

    }

增加表类:

class Department
    {
        private int _id;
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        private string _deptName;
        public string DeptName
        {
            get { return _deptName; }
            set{_deptName = value ;}
        }

    }

表类接口:

//IDepartment接口,用户客户端访问,解除与具体数据库访问的耦合
    interface IDepartment
    {
        void Insert(Department department);
        Department GetDepartment(int id);
    }

具体数据库类:

//用于访问SQL的Department

    class SqlserverDepartment:IDepartment 
    {
        public void Insert(Department department)
        {
            Console.WriteLine("在SQL中给Department表中增加一条记录");
        }

        public Department GetDepartment(int id)
        {
            Console.WriteLine("在SQL中根据ID得到department表一条记录");
            return null;
        }
    }

//用于访问Acess的Department

    class AccessDepartment:IDepartment //同SQL类
    {
        public void Insert(Department department)
        {
            Console.WriteLine("在Access中给Department表中增加一条记录");
        }

        public Department GetDepartment(int id)
        {
            Console.WriteLine("在Access中根据ID得到department表一条记录");
            return null;
        }
    }

客户端代码:

class Program
    {
        static void Main(string[] args)
        {
            User user = new User();
            Department dept = new Department();

            //只需确定实例化哪一个数据库访问对象给factory即可(SQL server factory或access factory)

            IFactory factory = new AccessFactory();

            IUser iu = factory.CreateUser();  //此时已与具体的数据库访问解除了依赖

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

            IDepartment id = factory.CreateDepartment();
            id.Insert(dept);
            id.GetDepartment(1);
            id.GetDepartment(1);

            Console.Read();
        }
    }

效果图:

抽象工厂

拓展

反射技术

格式:

反射技术的格式是: Assembly.Load(“程序集名称”).CreateInstance(“命名空间.类名称”)
需要引用using system.Reflection;这个命名空间

具体:略

后记

这个模式的一个重点就是区别开与简单工厂工厂方法模式的不同。
难点就是容易混淆诸多类,要先缕清结构图,再去进行代码敲写。
逻辑关系很重要!

猜你喜欢

转载自blog.csdn.net/carrie_q/article/details/80550988
今日推荐