系统架构技能之设计模式-抽象工厂模式-阿里云开发者社区

开发者社区> 嗯哼9925> 正文

系统架构技能之设计模式-抽象工厂模式

简介:
+关注继续查看

一、上篇回顾

        上篇我们主要讲述了简单工厂模式和工厂模式。并且分析了每种模式的应用场景和一些优缺点,我们现在来回顾一下:

        简单工厂模式:一个工厂负责所有类型对象的创建,不支持无缝的新增新的类型对象的创建。

        工厂模式:多个工厂负责多个类型对象的创建,每个工厂只负责具体类型对象的创建,支持无缝的新增类型对象的创建,需要实现工厂接口类和具体的类型对象类。

        我们来简单的对比下这2个模式的优缺点:

模式名称 优点 缺点
简单工厂模式 一个工厂负责所有对象的创建,简单灵活 不符合高内聚的原则,不支持无缝的扩展
工厂模式 可以无缝的新增类型,每个工厂职责单一,符合高内聚的原则 工厂类太多,难以维护。

        工厂模式,很优雅的解决了应用程序使用对象时的无限new()的操作,同时降低了系统应用之间的耦合性,提高了系统的可维护性和适应性。

二、摘要

        本文主要是针对创建型模式中的抽象工厂模式进行讲述,抽象工厂模式是在简单工厂模式的基础上扩展而成的新模式,将简单工厂中的对象的创建过程进行了很优雅的动态配置来完成无

缝的扩展,当然通过一些扩展,可以构建出可支持动态新增或者删除对象的抽象工厂模式。本文将会给出具体的实现方案,相比工厂模式,抽象工厂模式是一个工厂负责多个对象的创建,返回

的具体的类型是这个对象的抽象类型。这样,在客户端引用的时候只需要使用这个工厂返回的对象类型,抽象工厂会自动根据对象的类型动态的创建这个类型对象的实例。大体的过程如下:

           image

上面的图片呢,主要是针对经典的抽象工厂模式给出了一个实现草图的模拟,而我们在实际的项目中可能并不希望给出这么多的抽象工厂工厂实现,我只想给出一个通用的抽象

工厂实现,通过静态方法直接调用,返回我想要的对象类型的实例,而且这个对象类型是可以动态配置的,那么我们如何做到呢?这就是本篇需要讨论的实现方案。本篇将会从

以下几点进行讲述抽象工厂模式:

1、抽象工厂模式的简单实例代码-这里给出的是经典的抽象工厂模式实例代码。我们从经典的实例代码中可以看出这个工厂模式的一些缺点。

          2、根据经典工厂模式的缺点,我们给出改进的方案,进一步给出项目中可以使用的通用方案实现。

          3、给出上篇中的通过委托来实现的工厂模式方案。

          4、通过特性+反射的形式来动态的创建对象。

三、本文大纲

       a、上篇回顾。

       b、摘要。

       c、本文大纲。

       d、抽象工厂模式的特点及使用场景。

       e、抽象工厂模式的实现方案。

       f、抽象工厂模式使用总结。

       g、系列进度。

       h、下篇预告。

四、抽象工厂模式的特点及使用场景

        抽象工厂可以说是三类工厂模式中使用最广泛的,也是最受大家喜爱的模式之一,因为抽象工厂模式解决了一系列相互依赖的对象或者有组合关系的对象的创建过程。举个简单的例子来

说,我们以电脑的显卡和风扇来说吧,我们知道显卡一般在玩游戏的时候,由于渲染图形会产生大量的热量,如果没有好的风扇那么可能无法达到好的散热的效果,这个时候我们可以把显卡和

风扇的创建放在一个抽象工厂中进行创建,因为这2个对象是具有依赖关系的对象,那么我们来给出这个例子的完整实例代码:

        先看看2个对象类型的接口和抽象工厂的接口定义

    /// <summary> 
    /// 定义显卡抽象对象接口 
    /// </summary> 
    public interface IDisplayCard 
    { 
    }

    /// <summary> 
    /// 定义显卡风扇抽象对象接口 
    /// </summary> 
    public interface IDisplayFan 
    { 
    }

    /// <summary> 
    /// 定义显卡设备抽象工厂接口 
    /// </summary> 
    public  interface IAbstractDriveFactory 
    { 
        IDisplayCard CreateDisplayCard();

        IDisplayFan CreateDisplayFan(); 
    }

     我们来看看具体类型的实现和抽象工厂的具体实现。

    /// <summary> 
    /// 定义华硕显卡的具体对象 
    /// </summary> 
    public class DisplayCardAsus : IDisplayCard 
    { 
    }

    /// <summary> 
    /// 华硕显卡配套风扇 
    /// </summary> 
    public class DisplayFanAsus : IDisplayFan 
    { 
    }

    /// <summary> 
    /// 华硕显卡具体实现工厂 
    /// </summary> 
    public class DriveFactoryAsus : IAbstractDriveFactory 
    { 
        IDisplayCard CreateDisplayCardAsus() 
        { 
            return new DisplayCardAsus(); 
        }

        IDisplayFan CreateDisplayFanAsus() 
        { 
            return new DisplayFanAsus(); 
        } 
    }

        通过上面的代码,我们给出了抽象工厂的一个经典实例的实现方案,当然这不是我们开发中使用的实际形式,那么实际我们在项目中如何使用这个抽象工厂模式呢?我们一般是改进的方

案去使用这个抽象工厂模式,我们如何改进呢?对于目前的,如果我不光创建显卡设备和配套的风扇设备,我还想创建其他的类型的东西,这时候可能我们定义的抽象工厂就无法满足具有相互

依赖或者组合关系的对象类型实例的创建工作了,那么我们如何改进呢,这就是下面要讲述的几类方案。

五、抽象工厂模式的实现方案

     5.1、通过配置文件来实现

  • 我们先给出基于上面的经典抽象工厂的一个改进的方案,可以支持动态配置的抽象工厂,一个工厂负责动态的创建一些列的可动态配置的对象列表,我们如何做呢,我想一提到配置。大家都知道要么是通过XML文件来实现或者是通过泛型集合来做。我们这里可以提供的方案是这样的,通过工厂初始化时从配置文件中读取配置项,构造一个字典,然后从这个字典中查询要创建的类型是否在字典中,如果在字典中存在则创建这个类型的对象,否则返回NULL,我们这里通过泛型来实现。
  • 我们来看看具体的代码实现吧:

    /// <summary> 
    /// 定义抽象工厂接口 
    /// </summary> 
    public  interface IAbstractFactory 
    { 
        /// <summary> 
        /// 通用的泛型对象创建工厂 
        /// </summary> 
        /// <typeparam name="T"></typeparam> 
        /// <returns></returns> 
        T Create<T>(); 
    }

给出具体的实现这个接口的抽象工厂类

   /// <summary> 
   /// 具体的通用工厂实现 
   /// </summary> 
   public  class AbstractFactory : IAbstractFactory 
   { 
       private static readonly IDictionary<Type, Type> instances = null;

       public static AbstractFactory() 
       { 
           //从具体的配置项中读取,从配置文件中读取或者通过某个方法来硬编码实现等。 
           //这里推荐的做饭是从配置文件中读取。 
           instances = new Dictionary<Type, Type>(); 
           instances.Add(Type.GetType(""), Type.GetType("")); 
           instances.Add(Type.GetType(""), Type.GetType("")); 
       } 
       public T Create<T>() 
       { 
           if (!instances.ContainsKey(typeof(T))) 
               return default(T);

           Type typeInstance = instances[typeof(T)];

           T obj = (T)Activator.CreateInstance(typeInstance);

           return obj; 
       } 
   }

  • 通过上面给出的代码,基本上可以满足一般项目的需求,大家当然有好的思路和建议也可以提出,给出更好的改进方案,下面我给出大概的配置文件格式,其实就是父子级节点,父级节点是负责创建的工厂
  • 类,那么这个父节点下的子节点就是工厂要创建的具体的对象类型。

image

上图中描述的思路,我们大概知道了,对应这样的一个支持多个具有依赖关系或者组合关系的对象的动态抽象工厂的实现,那么如果我们想实现支持多个具有依赖关系或者组合

关系的不同的创建形式的通用创建工厂时,我们如何来做呢?同上面的思路,只不过我们外部需要再添加一个字典,负责类型和抽象工厂的映射,即抽象工厂可以创建的字典列

表及抽象工厂具体实例类型之间的键值对关系,或者通过配置文件来组织父子级的关系。我们大概的看下配置文件的组织吧:

<?xml version="1.0" encoding="utf-8" ?> 
<AbstractFactory> 
    <FactorySections> 
        <FactorySection name="ProductFactory" type="DesignPattern.ProductFactory"> 
            <ObjectInstance name="" type=""/> 
            <ObjectInstance name="" type=""/> 
            <ObjectInstance name="" type=""/> 
            <ObjectInstance name="" type=""/> 
        </FactorySection> 
        <FactorySection name="FoodFactory" type="DesignPattern.FoodFactory"> 
            <ObjectInstance name="" type=""/> 
            <ObjectInstance name="" type=""/> 
            <ObjectInstance name="" type=""/> 
            <ObjectInstance name="" type=""/> 
        </FactorySection> 
        <FactorySection name="BookFactory" type="DesignPattern.BookFactory"> 
            <ObjectInstance name="" type=""/> 
            <ObjectInstance name="" type=""/> 
            <ObjectInstance name="" type=""/> 
            <ObjectInstance name="" type=""/> 
        </FactorySection> 
    </FactorySections> 
</AbstractFactory>

          那么具体的抽象工厂的代码又如何组织呢?如下形式:

    /// <summary> 
    /// 具体的通用工厂实现 
    /// </summary> 
    public  class AbstractFactory : IAbstractFactory 
    { 
        /// <summary> 
        /// 工厂与工厂能够创建的对象类型字典之间的映射字典 
        /// </summary> 
        private static readonly IDictionary<Type, Dictionary<Type, Type>> typeMapper = null; 
        private Type factoryType = null;

        public static AbstractFactory() 
        { 
            //从具体的配置项中读取,从配置文件中读取或者通过某个方法来硬编码实现等。 
            //这里推荐的做饭是从配置文件中读取。 
            //根据配置文件中的ObjectInstance 节点放在对应的工厂下的字典中 
            //每个工厂节点FactorySection 就会创建一个字典,并且将这个工厂能够创建的类型放在这个字典中 
            typeMapper = new Dictionary<Type, Dictionary<Type, Type>>(); 
        }

        public  AbstractFactory(string typeName) 
        { 
            this.factoryType = Type.GetType(typeName); 
        } 
        public T Create<T>() 
        { 
            if(typeMapper.ContainsKey(this.factoryType)) 
                return default(T);

            Dictionary<Type, Type> instances = typeMapper[this.factoryType];

            if (!instances.ContainsKey(typeof(T))) 
                return default(T);

            Type typeInstance = instances[typeof(T)];

            T obj = (T)Activator.CreateInstance(typeInstance);

            return obj; 
        } 
    }

通过上面的代码我们就给出了一个通用的抽象工厂的可行的解决方案。

5.2、通过委托来实现工厂模式

          我们先要定义一个委托:

public delegate string DelegateFunctionHandler(string userName);

基于这个委托的工厂实现方案

    /// <summary> 
    /// 具体的通用工厂实现 
    /// </summary> 
    public  class DegelateFactory  
    { 
        private DelegateFunctionHandler handler = null;

        public static  DelegateFunctionHandler Create() 
        { 
            if (handler == null) 
                handler = new DelegateFunctionHandler(this.Test);

            return handler; 
        }

        public string Test(string name) 
        { 
            return "Test!"; 
        }

    }

           工厂返回一个委托类型的对象,当然我上面为了简单给出的test方法其实就是工厂内部的方法,当然这里还可以进行相应的改进,也可以通过配置文件来完成,通过配置文件把相应相

应的委托事件方法,通过配置来通过工厂动态的创建。下面给出个思路吧,具体的实现我就不贴出来了:

image也希望大家给出更好的实现思路和方案。希望能多多的交流。

六、抽象工厂模式使用总结

         通过上面的实现方式和思路,我们来对比一下抽象工厂、工厂模式、简单工厂模式之间的差异和相同点。

         相同点

          1、都是为客户调用程序与具体的对象类型之间提供了一个解耦作用,这里怎么说呢?其实就是应用程序不关心这个对象是怎么出来的,只关系如何使用这个对象,而且以后就算对象发生变化,那么也不需

要修改用户应用程序的代码。

         2、提高了程序的可维护性和低耦合性。

         异同点

         1、简单工厂模式:是简单的一些列没有任何依赖关系的对象的创建,内部包含复杂的逻辑关系,一半是通过配置或者参数来进行创建对象,适合对象类型不多,并且不会经常新增的情况下。

               工厂模式:每个工厂负责具体类型对象的创建,提供了可以动态新增产品类型的创建,并不需要修改现有的程序就可以无缝的新增产品类型。

               抽象工厂模式:支持动态的新增对象类型和新增工厂类型,实现多种依赖关系的对象或者组合关系的创建,适合现有项目中的对象创建过程。

         2、简单工厂模式:内部逻辑复杂,不符合高内聚的原则。

               工厂模式:每次新增一个对象类型,就必须新增一个对应的创建工厂,无疑这是一个非常大的工作量。

               抽象工厂模式:是在简单工厂模式的基础上经过改进具有前2个模式的优点,又屏蔽了他们的一些缺点。

当然我们在具体的项目中,还是需要具体的情况具体分析,一般情况下,我们对于这种数据库平滑迁移时,简单工厂可能比其他2类工厂更容易做,也很灵活。

七、系列进度。

     创建型

        1、系统架构技能之设计模式-单件模式

        2、系统架构技能之设计模式-工厂模式

        3、系统架构技能之设计模式-抽象工厂模式

        4、系统架构技能之设计模式-创建者模式

        5、系统架构技能之设计模式-原型模式

        结构型

        1、系统架构技能之设计模式-组合模式

        2、系统架构技能之设计模式-外观模式

        3、系统架构技能之设计模式-适配器模式

        4、系统架构技能之设计模式-桥模式

        5、系统架构技能之设计模式-装饰模式

        6、系统架构技能之设计模式-享元模式

        7、系统架构技能之设计模式-代理模式

        行为型

        1、系统架构技能之设计模式-命令模式

        2、系统架构技能之设计模式-观察者模式

        3、系统架构技能之设计模式-策略模式

        4、系统架构技能之设计模式-职责模式

        5、系统架构技能之设计模式-模板模式

        6、系统架构技能之设计模式-中介者模式

        7、系统架构技能之设计模式-解释器模式

八、下篇预告。

       下篇将会针对创建者模式进行讲述,该模式也是创建型模式中最复杂的设计模式之一,该 模式是对一个对象的各个创建部分进行划分,最后创建出完整的对象,当然这里面的实现方式可以说还是

那几类思路,我将会给出几个方案的关键代码,希望大家多提宝贵意见,错误之处还请指出,请大家继续支持。





本文转自何戈洲博客园博客,原文链接:http://www.cnblogs.com/hegezhou_hot/archive/2010/12/01/1893388.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Unity【话大】设计模式之抽象工厂
前言:笔者在最开始写程序的时候经常会遇到一种情况,例如更改一个字段、或者添加一种小功能,就要把原来写过的东西几乎废弃掉,或者更改大量以前写过的代码。又或者自己写的东西时间久了再去回顾,完全找不到到时为什么这么写的头绪,如果遇到了Bug更是无法快速定位在哪里小范围出现的问题。
950 0
架构那点事系列一 - 设计模式前章
                                        ----能够正视失败和错误,而不回避和掩盖,正是职业架构师的宝贵素养!!!       首先,我们需要明白的是何为架构,以我看来,架构更多关注的是高层设计(所谓的high-level Design),它是一组有关如何确定软件系统的组织机构的重要决策。感兴趣的朋友可以查看这篇文章来深入理解一下架构的概念
1156 0
设计模式之四(抽象工厂模式第三回合)
原文:设计模式之四(抽象工厂模式第三回合) 前言 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 抽象工厂模式最大的好处便是易于交换产品系列,由于具体工厂类,例如IFactory factory=new AccessFactory(),在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
673 0
设计模式之四(抽象工厂模式第一回合)
原文:设计模式之四(抽象工厂模式第一回合) 前言 首先关于抽象工厂模式的学习,我们需要慢慢的,由浅入深的进入。不能单刀直入,否则可能达不到预期学明白的目标。 第一回合    首先我们从最简单的数据访问程序开始吧。
634 0
设计模式之四(抽象工厂模式第二回合)
原文:设计模式之四(抽象工厂模式第二回合) 前言 在第一回合中留下的问题,http://www.cnblogs.com/aehyok/archive/2013/05/19/3087497.html,现在就先处理一个简单的,只添加一个Department表。
722 0
设计模式快速学习(二)抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
766 0
+关注
4463
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载