C#设计模式学习笔记:(3)抽象工厂模式

    本笔记摘抄自:http://www.javashuo.com/article/p-hjobwtrt-hy.html,记录一下学习过程以备后续查用。html

    1、引言数据库

    接上一篇C#设计模式学习笔记:简单工厂模式(工厂方法模式前奏篇),经过简单工厂模式的了解,它的缺点就是随着需求的变化咱们要不停地修改工厂里设计模式

    上一篇文章咱们讲了工厂方法模式,它是为了解决简单工厂模式所面对的问题:若是咱们增长新的产品,工厂类的方法就要修改自己的代码,增长产品越ide

多,其逻辑越复杂,同时这样的修改也不符合开放闭合原则OCP--对增长代码开放,对修改代码关闭。为了解决简单工厂的问题,咱们引出了工厂方法模式,工具

经过子类化工厂类,解决了工厂类责任的划分,使得产品和相应的工厂一一对应,符合了OCP。post

    若是咱们要设计一套房子,固然咱们知道房子是由房顶、地板、窗户、房门等组成的,先设计一套古典风格的房子,再建立一套现代风格的房子,再建立学习

一套欧式风格的房子,这么多套房子,咱们该怎么办呢?今天咱们要讲的抽象工厂模式能够很好地解决多套变化的问题。ui

    2、抽象工厂模式介绍atom

    抽象工厂模式:英文名称--Abstract Factory Pattern;分类--建立型。url

    2.一、动机(Motivate)

    在软件系统中,常常面临着"一系列相互依赖的对象"的建立工做,同时,因为需求的变化,每每存在更多系列对象的建立工做。如何应对这种变化?如何

绕过常规的对象建立方法(new),提供一种"封装机制"来避免客户程序和这种"多系列具体对象建立工做"的紧耦合?

    2.二、意图(Intent)

    提供一个建立一系列相关或相互依赖对象的接口,而无需指定它们具体的类。——《设计模式》GoF

    2.三、结构图(Structure)

    该图是抽象工厂的UML图,结合抽象工厂的意图、动机和图示来理解该模式,今天咱们就以建设房子为例来讲明抽象工厂的实现机理。

    2.四、模式的组成

    从上图能够看出,在抽象工厂模式的结构图有如下角色:

    1)抽象产品类角色(AbstractProduct):为抽象工厂中相互依赖的每种产品定义抽象接口对象,也能够这样说,有几种产品,就要声明几个抽象角色,

每个抽象产品角色和一种具体的产品相匹配。

    2)具体产品类(ConcreteProduct):具体产品类实现了抽象产品类,是针对某个具体产品的实现的类型。

    3)抽象工厂类角色(AbstractFactory):定义了建立一组相互依赖的产品对象的接口操做,每种操做和每种产品一一对应。

    4)具体工厂类角色(ConcreteFactory):实现抽象类里全部抽象接口操做,能够建立某系列具体的产品,这些具体的产品是“抽象产品类角色”的子类。

    2.五、抽象工厂的具体代码实现

    随着咱们年龄的增加,咱们也到告终婚的年龄,结婚首要的问题就是房子的问题。假设我有一个颇有钱的爸爸(呃,发梦中……),个人哥哥们但愿能有

一套欧式风格的房子,再加上田园风光,清闲自在。而我就不同了,我但愿有一套现代样式的房子。因为房子由房顶、地板、窗户和房门组成(其余组

件暂时省略),每套房子的房顶、地板、窗户和房门都是一个体系的。

    下面让咱们看看如何使用抽象工厂模式来实现不一样房屋的建造:

    class Program
    {
        /// <summary>
        /// 房顶抽象类,子类的房顶必须继承该类。
        /// </summary>
        public abstract class Roof
        {
            /// <summary>
            /// 建立房顶
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 地板抽象类,子类的地板必须继承该类。
        /// </summary>
        public abstract class Floor
        {
            /// <summary>
            /// 建立地板
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 窗户抽象类,子类的窗户必须继承该类。
        /// </summary>
        public abstract class Window
        {
            /// <summary>
            /// 建立窗户
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 房门抽象类,子类的房门必须继承该类。
        /// </summary>
        public abstract class Door
        {
            /// <summary>
            /// 建立房门
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 欧式的房顶
        /// </summary>
        public class EuropeanRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("建立欧式的房顶");
            }
        }

        /// <summary>
        /// 欧式的地板
        /// </summary>
        public class EuropeanFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("建立欧式的地板");
            }
        }

        /// <summary>
        ///欧式的窗户
        /// </summary>
        public class EuropeanWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("建立欧式的窗户");
            }
        }

        /// <summary>
        /// 欧式的房门
        /// </summary>
        public class EuropeanDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("建立欧式的房门");
            }
        }

        /// <summary>
        /// 现代的房顶
        /// </summary>
        public class ModernizationRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("建立现代的房顶");
            }
        }

        /// <summary>
        /// 现代的地板
        /// </summary>
        public class ModernizationFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("建立现代的地板");
            }
        }

        /// <summary>
        /// 现代的窗户
        /// </summary>
        public class ModernizationWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("建立现代的窗户");
            }
        }

        /// <summary>
        /// 现代的房门
        /// </summary>
        public class ModernizationDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("建立现代的房门");
            }
        }

        /// <summary>
        /// 抽象工厂类,提供建立不一样类型房子的接口。
        /// </summary>
        public abstract class AbstractFactory
        {
            //抽象工厂提供建立一系列产品的接口,此处给出了房顶、地板、窗户和房门的建立接口。
            public abstract Roof CreateRoof();
            public abstract Floor CreateFloor();
            public abstract Window CreateWindow();
            public abstract Door CreateDoor();
        }

        /// <summary>
        /// 欧式风格房子的工厂,负责建立欧式风格的房子。
        /// </summary>
        public class EuropeanFactory : AbstractFactory
        {
            //制做欧式房顶
            public override Roof CreateRoof()
            {
                return new EuropeanRoof();
            }

            //制做欧式地板
            public override Floor CreateFloor()
            {
                return new EuropeanFloor();
            }

            //制做欧式窗户
            public override Window CreateWindow()
            {
                return new EuropeanWindow();
            }

            //制做欧式房门
            public override Door CreateDoor()
            {
                return new EuropeanDoor();
            }
        }

        /// <summary>
        /// 如今风格房子的工厂,负责建立现代风格的房子。
        /// </summary>
        public class ModernizationFactory : AbstractFactory
        {
            //制做现代房顶
            public override Roof CreateRoof()
            {
                return new ModernizationRoof();
            }

            //制做现代地板
            public override Floor CreateFloor()
            {
                return new ModernizationFloor();
            }

            //制做现代窗户
            public override Window CreateWindow()
            {
                return new ModernizationWindow();
            }

            //制做现代房门
            public override Door CreateDoor()
            {
                return new ModernizationDoor();
            }
        }

        static void Main(string[] args)
        {
            #region 抽象工厂模式
            //欧式风格的房子
            AbstractFactory europeanFactory = new EuropeanFactory();
            europeanFactory.CreateRoof().Create();
            europeanFactory.CreateFloor().Create();
            europeanFactory.CreateWindow().Create();
            europeanFactory.CreateDoor().Create();

            //现代风格的房子
            AbstractFactory modernizationFactory = new ModernizationFactory();
            modernizationFactory.CreateRoof().Create();
            modernizationFactory.CreateFloor().Create();
            modernizationFactory.CreateWindow().Create();
            modernizationFactory.CreateDoor().Create();

            Console.Read();
            #endregion
        }
    }
View Code

    运行结果以下:

    2.六、 抽象工厂应对需求变动

    假设个人姐姐一看咱们的房子很好,她但愿有一套古典风格的房子,怎么处理呢?

    class Program
    {
        /// <summary>
        /// 房顶抽象类,子类的房顶必须继承该类。
        /// </summary>
        public abstract class Roof
        {
            /// <summary>
            /// 建立房顶
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 地板抽象类,子类的地板必须继承该类。
        /// </summary>
        public abstract class Floor
        {
            /// <summary>
            /// 建立地板
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 窗户抽象类,子类的窗户必须继承该类。
        /// </summary>
        public abstract class Window
        {
            /// <summary>
            /// 建立窗户
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 房门抽象类,子类的房门必须继承该类。
        /// </summary>
        public abstract class Door
        {
            /// <summary>
            /// 建立房门
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 欧式的房顶
        /// </summary>
        public class EuropeanRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("建立欧式的房顶");
            }
        }

        /// <summary>
        /// 欧式的地板
        /// </summary>
        public class EuropeanFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("建立欧式的地板");
            }
        }

        /// <summary>
        ///欧式的窗户
        /// </summary>
        public class EuropeanWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("建立欧式的窗户");
            }
        }

        /// <summary>
        /// 欧式的房门
        /// </summary>
        public class EuropeanDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("建立欧式的房门");
            }
        }

        /// <summary>
        /// 现代的房顶
        /// </summary>
        public class ModernizationRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("建立现代的房顶");
            }
        }

        /// <summary>
        /// 现代的地板
        /// </summary>
        public class ModernizationFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("建立现代的地板");
            }
        }

        /// <summary>
        /// 现代的窗户
        /// </summary>
        public class ModernizationWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("建立现代的窗户");
            }
        }

        /// <summary>
        /// 现代的房门
        /// </summary>
        public class ModernizationDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("建立现代的房门");
            }
        }

        /// <summary>
        ///古典的房顶
        /// </summary>
        public class ClassicalRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("建立古典的房顶");
            }
        }

        /// <summary>
        /// 古典的地板
        /// </summary>
        public class ClassicalFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("建立古典的地板");
            }
        }

        /// <summary>
        /// 古典的窗户
        /// </summary>
        public class ClassicalWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("建立古典的窗户");
            }
        }

        /// <summary>
        /// 古典的房门
        /// </summary>
        public class ClassicalDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("建立古典的房门");
            }
        }

        /// <summary>
        /// 抽象工厂类,提供建立不一样类型房子的接口。
        /// </summary>
        public abstract class AbstractFactory
        {
            //抽象工厂提供建立一系列产品的接口,此处给出了房顶、地板、窗户和房门的建立接口。
            public abstract Roof CreateRoof();
            public abstract Floor CreateFloor();
            public abstract Window CreateWindow();
            public abstract Door CreateDoor();
        }

        /// <summary>
        /// 欧式风格房子的工厂,负责建立欧式风格的房子。
        /// </summary>
        public class EuropeanFactory : AbstractFactory
        {
            //制做欧式房顶
            public override Roof CreateRoof()
            {
                return new EuropeanRoof();
            }

            //制做欧式地板
            public override Floor CreateFloor()
            {
                return new EuropeanFloor();
            }

            //制做欧式窗户
            public override Window CreateWindow()
            {
                return new EuropeanWindow();
            }

            //制做欧式房门
            public override Door CreateDoor()
            {
                return new EuropeanDoor();
            }
        }

        /// <summary>
        /// 如今风格房子的工厂,负责建立现代风格的房子。
        /// </summary>
        public class ModernizationFactory : AbstractFactory
        {
            //制做现代房顶
            public override Roof CreateRoof()
            {
                return new ModernizationRoof();
            }

            //制做现代地板
            public override Floor CreateFloor()
            {
                return new ModernizationFloor();
            }

            //制做现代窗户
            public override Window CreateWindow()
            {
                return new ModernizationWindow();
            }

            //制做现代房门
            public override Door CreateDoor()
            {
                return new ModernizationDoor();
            }
        }

        /// <summary>
        /// 古典风格房子的工厂,负责建立古典风格的房子。
        /// </summary>
        public class ClassicalFactory : AbstractFactory
        {
            //建立古典房顶
            public override Roof CreateRoof()
            {
                return new ClassicalRoof();
            }

            //建立古典地板
            public override Floor CreateFloor()
            {
                return new ClassicalFloor();
            }

            //建立古典窗户
            public override Window CreateWindow()
            {
                return new ClassicalWindow();
            }

            //建立古典房门
            public override Door CreateDoor()
            {
                return new ClassicalDoor();
            }
        }

        static void Main(string[] args)
        {
            #region 抽象工厂模式
            //欧式风格的房子
            AbstractFactory europeanFactory = new EuropeanFactory();
            europeanFactory.CreateRoof().Create();
            europeanFactory.CreateFloor().Create();
            europeanFactory.CreateWindow().Create();
            europeanFactory.CreateDoor().Create();

            //现代风格的房子
            AbstractFactory modernizationFactory = new ModernizationFactory();
            modernizationFactory.CreateRoof().Create();
            modernizationFactory.CreateFloor().Create();
            modernizationFactory.CreateWindow().Create();
            modernizationFactory.CreateDoor().Create();

            //古典风格的房子
            AbstractFactory classicalFactory = new ClassicalFactory();
            classicalFactory.CreateRoof().Create();
            classicalFactory.CreateFloor().Create();
            classicalFactory.CreateWindow().Create();
            classicalFactory.CreateDoor().Create();

            Console.Read();
            #endregion
        }
    }
View Code

    运行结果以下:

    从上面代码能够看出,须要添加5个类:4个类分别建立古典风格的房顶、地板、窗户和房门的具体产品,另一个是古典风格房子的工厂类,负责建立

古典风格的房子。

    从上面代码能够看出,抽象工厂对于系列产品的变化支持开闭原则(对扩展开放,对修改封闭),扩展起来很是简便。可是,抽象工厂对于增长新产品

这种状况就不支持开闭原则,由于要修改建立系列产品的抽象基类AbstractFactory,增长相应产品的建立方法,这也是抽象工厂的缺点所在。

    3、抽象工厂的实现要点

    1)若是没有应对“多系列对象建立”的需求变化,则没有必要使用AbstractFactory模式,这时候使用简单工厂模式彻底能够。

    2)"系列对象"指的是这些对象之间有相互依赖、或做用的关系,例如游戏开发场景中“道路”与“房屋”的依赖,“道路”与“地道”的依赖。

    3)AbstractFactory模式主要在于应对“新系列”的需求变更,其缺点在于难以应对“新对象”的需求变更

    4)AbstractFactory模式常常和FactoryMethod模式共同组合来应对“对象建立”的需求变化。

    3.1抽象工厂模式的优势

    抽象工厂模式将系列产品的建立工做延迟到具体工厂的子类中,咱们声明工厂类变量的时候使用的是抽象类型,同理,咱们使用产品类型也是抽象类型,

这样作能够尽量地减小客户端代码与具体产品类之间的依赖,从而下降了系统的耦合度。耦合度下降了,对于后期的维护和扩展就更有利,这就是抽象

工厂模式的优势所在。

    可能有人会说在Main方法里面(客户端)仍是会使用具体的工厂类,对的。这个其实咱们能够经过.Net配置文件把这部分移出去,把依赖关系放到配置文

件中。若是有新的需求咱们只须要修改配置文件,根本就不须要修改代码了,让客户代码更稳定。依赖关系确定会存在,咱们要作的就是下降依赖,想彻底

去除很难,也不现实。

    3.2抽象工厂模式的缺点

    有优势确定就有缺点,由于每种模式都有它的使用范围,或者说不能解决的问题就是缺点。抽象工厂模式很难支持增长新产品的变化,这是由于抽象工厂

接口中已经肯定了能够被建立的产品集合,若是须要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类以及全部子类的改变,这样

也就违背了开闭原则。

    3.3抽象工厂模式的使用场景

    若是系统须要多套的代码解决方案,而且每套的代码方案中又有不少相互关联的产品类型,而且在系统中能够相互替换地使用一套产品的时候就可使用

该模式,客户端不须要依赖具体实现。

    4、.NET中抽象工厂模式实现

    微软的类库发展了这么多年,设计模式在里面有大量的应用。抽象工厂模式在.NET类库中也存在着大量的使用,好比和操做数据库有关的类型,这个类是

System.Data.Common.DbProviderFactory,此类位于System.Data.dll程序集中。该类扮演抽象工厂模式中抽象工厂的角色,咱们能够用ILSpy反编译工具查

看该类的实现:

    /// 扮演抽象工厂的角色
    /// 建立链接数据库时所须要的对象集合
    /// 这个对象集合包括有DbConnection对象(抽象产品类)、DbCommand类、DbDataAdapter类,针对不一样的具体工厂都须要实现该抽象类中的方法。

    public abstract class DbProviderFactory
    {
        public virtual bool CanCreateDataSourceEnumerator
        {
            get
            {
                return false;
            }
        }

        public virtual DbCommand CreateCommand()
        {
            return null;
        }

        public virtual DbCommandBuilder CreateCommandBuilder()
        {
            return null;
        }

        public virtual DbConnection CreateConnection()
        {
            return null;
        }

        public virtual DbConnectionStringBuilder CreateConnectionStringBuilder()
        {
            return null;
        }

        public virtual DbDataAdapter CreateDataAdapter()
        {
            return null;
        }

        public virtual DbParameter CreateParameter()
        {
            return null;
        }

        public virtual CodeAccessPermission CreatePermission(PermissionState state)
        {
            return null;
        }

        public virtual DbDataSourceEnumerator CreateDataSourceEnumerator()
        {
            return null;
        }
    }
View Code

    DbProviderFactory类是一个抽象工厂类,该类提供了建立数据库链接时所须要的对象集合的接口,实际建立工做在其子类工厂中进行。微软使用的是

SQL Server数据库,所以提供了链接SQL Server数据的具体工厂实现,具体代码能够用反编译工具查看。

    SqlClientFactory扮演着具体工厂的角色,用来建立链接SQL Server数据所须要的对象:

    public sealed class SqlClientFactory : DbProviderFactory, IServiceProvider
    {
        public static readonly SqlClientFactory Instance = new SqlClientFactory();

        public override bool CanCreateDataSourceEnumerator
        {
            get
            {
                return true;
            }
        }

        private SqlClientFactory()
        {
        }

        public override DbCommand CreateCommand()
        {
            return new SqlCommand();
        }

        public override DbCommandBuilder CreateCommandBuilder()
        {
            return new SqlCommandBuilder();
        }

        public override DbConnection CreateConnection()
        {
            return new SqlConnection();
        }

        public override DbConnectionStringBuilder CreateConnectionStringBuilder()
        {
            return new SqlConnectionStringBuilder();
        }

        public override DbDataAdapter CreateDataAdapter()
        {
            return new SqlDataAdapter();
        }

        public override DbParameter CreateParameter()
        {
            return new SqlParameter();
        }

        public override CodeAccessPermission CreatePermission(PermissionState state)
        {
            return new SqlClientPermission(state);
        }

        public override DbDataSourceEnumerator CreateDataSourceEnumerator()
        {
            return SqlDataSourceEnumerator.Instance;
        }

        object IServiceProvider.GetService(Type serviceType)
        {
            object result = null;
            if (serviceType == GreenMethods.SystemDataCommonDbProviderServices_Type)
            {
                result = GreenMethods.SystemDataSqlClientSqlProviderServices_Instance();
            }
            return result;
        }
    }
View Code

    OdbcFactory也是具体工厂类:

    public sealed class OdbcFactory : DbProviderFactory
    {
        public static readonly OdbcFactory Instance = new OdbcFactory();

        private OdbcFactory()
        {
        }

        public override DbCommand CreateCommand()
        {
            return new OdbcCommand();
        }

        public override DbCommandBuilder CreateCommandBuilder()
        {
            return new OdbcCommandBuilder();
        }

        public override DbConnection CreateConnection()
        {
            return new OdbcConnection();
        }

        public override DbConnectionStringBuilder CreateConnectionStringBuilder()
        {
            return new OdbcConnectionStringBuilder();
        }

        public override DbDataAdapter CreateDataAdapter()
        {
            return new OdbcDataAdapter();
        }

        public override DbParameter CreateParameter()
        {
            return new OdbcParameter();
        }

        public override CodeAccessPermission CreatePermission(PermissionState state)
        {
            return new OdbcPermission(state);
        }
    }
View Code

    固然,咱们也有OleDbFactory类型,都是负责具体的数据库操做。DbProviderFactory就是抽象工厂模式UML里面AbstractFactory类型,其它具体的工厂类

型继承于DbProviderFactory类型。

    5、总结

    学习设计模式不能死学,要把握核心点和使用场景,关键点是面向对象设计模式的基本原则。有了原则,考虑问题就不会跑偏,而后再仔细把握每种模式的

使用场景和要解决的问题,多写写代码,多看看Net的类库,它是最好的教材。

相关文章
相关标签/搜索