设计模式系列-创建者模式

简介:

一、上篇回顾

        上篇我们主要讲述了抽象工厂模式和工厂模式。并且分析了该模式的应用场景和一些优缺点,并且给出了一些实现的思路和方案,我们现在来回顾一下:

        抽象工厂模式:一个工厂负责所有类型对象的创建,支持无缝的新增新的类型对象的创建。这种情况是通过配置文件来实现的,通过字典映射的方式来实现,不过可能效率上有点低下,可以通过优化的方式

来做,上篇中我们也给出了委托的工厂实现形式,相比之前的简单工厂模式和工厂模式有了更好的灵活性,并且对具有依赖关系或者组合关系的对象的创建尤为适合。

        上篇中,有不少的朋友提出了一些意见和建议,首先很感谢大伙的支持和鼓励,有朋友提出来,我画的图不够专业,专业人士应该用UML建模图来搞,我怎么说呢?我也同意这样的说法,但是我发现我通过

另外的直观的图形,大家一看就能更明白,结合代码,当然好的UML图,已经能表述清楚设计的思路和大体实现了,不过说实话,我看着就有点类,特别是UML图复杂的时候。所以我还是暂时先用这种一般的图

形来表述我理解的设计模式的思想,看看大伙是什么看法和意见,如果说都说说UML图的话,那么后面的相关模式,我会主要以UML专业图来绘制。

        我这里总结下我们以后项目中的可能会用到设计模式 之处或者系统架构的时候,一般情况下有这样的几类方案,我们可以在考虑系统的低耦合性的时候的设计:

       image基本上来说能掌握上面的几类情况,基本上设计出来的系统至少是可用的,不知道大家有没有更多意见和建议。有的请提出来,我会备

注在文章中。

二、摘要

        本文主要是针对创建型模式中的创建者模式进行讲述,创建者模式是创建型模式中最负责的一个设计模式了,创建者负责构建一个对象的各个部分,并且完成组装的过程,我们可以这么理解创建

者模式,创建者模式类似与一个步骤基本固定,但是每个步骤中的具体形式却又可以变化的这类对象的创建。也许这样说还是太抽象了,我们这么来理解吧,我感觉让人最容易理解的形式还是图形化

的形式,不但接受起来容易,并且让人映象深刻,不知道大家是不是和我有同感呢?下面我们给出一个简单的例子,通过图形化的流程来说明吧:我们这里以我们大伙平时最常见的做饭为例吧:

image可能我这里给出的流程只是我个人理解的或者看到的过程,不代表全部,呵呵,这里只是事例性的说明。

三、本文大纲

       a、上篇回顾。

       b、摘要。

       c、本文大纲。

       d、创建者模式的特点及使用场景。

       e、创建者模式的实现方案。

       f、创建者模式使用总结。

       g、系列进度。

       h、下篇预告。

四、创建者模式的特点及使用场景

      创建者模式主要是用于创建复杂的一些对象,这些对象的创建步骤基本固定,但是可能具体的对象的组成部分却又可以自由的变化,现实中的例子很多,但是可能大伙都比较容易理解的就是,我

们的自己花钱配置的台式机或者笔记本,可以 这样理解,这些硬件设备的各个零件,不管是CPU是Intel的还是AMD的,显卡是华硕的还是小影霸的,不管硬盘是西部数据的还是希捷的,其实想表述

的意思就是对象的具体的组成部分可以是变化的,但是可能我们发现对象的这些组成部分的组织起来的过程是相对固定的,那么我们就可以用创建者模式来做,并且我们引入一个引导者(Director)来

引导这个对象的组装过程。可以简单用图形化的过程来描述如下:

image我们上面说明了一个服装的大概生产过程,这里生产的顺序可能会发生变化,或者

生产的帽子,上衣等都会发生变化,但是服装的组装过程基本上变化不大,都是需要帽子,上衣,裤子的,这时候我们可以通过引导着负责组装这样的过程,然后我们在具体的每个部分可以是抽象接

口,根据不同的实现创建不同的帽子来完成变化。

五、创建者模式的实现方案

     5.1、经典的创建者模式实现

  •  
    • 我们先给出经典创建者模式的一个实现形式,然后针对这个经典模式后面提出几个改进方案,我们这里以上面讲述的服装的过程作为例子来说明下创建者模式的原理和思想,希望大家也能灵活的运用到实际的项目中去。达到学以致用的目的。

我们来看看具体的代码实现:

    

1
2
3
4
5
6
7
8
9
/// <summary>
/// 创建对象组织的所有构造步骤接口
/// </summary>
public  interface  IBuider
{
     void  BuilderPart1();
     void  BuilderPart2();
     void  BuilderPart3();
}

定义一个服装对象:

    

/// <summary>
/// 服装对象
/// </summary>
public  class  Dress
{
     /// <summary>
     /// 构建帽子
     /// </summary>
     public  void  BuildHat()
     {
         throw  new  NotImplementedException();
     }
     /// <summary>
     /// 构建上衣
     /// </summary>
     public  void  BuilderWaist()
     {
         throw  new  NotImplementedException();
     }
     /// <summary>
     /// 构建裤子
     /// </summary>
     public  void  BuilderTrousers()
     {
         throw  new  NotImplementedException();
     }
}

实现创建对象的具体步骤:

    

public  class  Builder : IBuider
{
      private  Dress _dress;
      public  Builder(Dress dress)
      {
          this ._dress = dress;
      }
     public  void  BuilderPart1()
     {
         this ._dress.BuildHat();
     }
     public  void  BuilderPart2()
     {
         this ._dress.BuilderWaist();
     }
     public  void  BuilderPart3()
     {
         this ._dress.BuilderTrousers();
     }
     public  Dress Build()
     {
         return  this ._dress;
     }
}

通过指导者指导对象的创建,而具体的对象的创建还是靠对象本身提供的相应方法,Builder只是调用对象的方法完成组装步骤。Builder内部提供一个返回构造后完整对象的方法,上面给出的方法是

Build()方法。

    

/// <summary>
/// 指导者
/// </summary>
public  class  Director
{
     public  void  Build(IBuider builder)
     {
         builder.BuilderPart1();
         builder.BuilderPart2();
         builder.BuilderPart3();
     }
}

通过上面的代码,我们给出了经典创建者模式的核心代码形式,那么针对上面无疑有以下的几个缺点:

1、Ibuilder接口必须定义完整的组装流程,一旦定义就不能随意的动态修改。

2、Builder与具体的对象之间有一定的依赖关系,当然这里可以通过接口来解耦来实现灵活性。

3、Builder必须知道具体的流程。

那么针对上面的几个问题,我们如何来解决呢?我想前面的创建型模式已经给我了足够的经验,还是通过配置文件或者其他的形式来提供灵活性。

  • 5.2、创建者模式特性+委托实现

   针对上面讲述的例子我们可以考虑如下的方式进行改进:

    我们先定义一个构造每个对象部分的委托,并且这个方法的参数是动态变化的:

    

/// <summary>
/// 定义通用的构造部分的委托
/// </summary>
public  delegate  void  BuildHandler( params  object [] items);

   我们通过定义标记来标识对象中的每个部分的构造步骤

    

/// <summary>
/// 为对象中的每个步骤打上标记
/// </summary>
[AttributeUsage(AttributeTargets.Method,AllowMultiple= false )]
public  class  BuildAttribute : Attribute
{
     private  MethodInfo hander;
     private  int  stepSort;
     public  MethodInfo BuildHandler
     {
         get
         {
             return  this .hander;
         }
         set
         {
             this .hander = value;
         }
     }
     public  int  StepSort
     {
         get
         {
             return  this .stepSort;
         }
         set
         {
             this .stepSort = value;
         }
     }
}

构造对象的统一接口

    

/// <summary>
/// 创建对象组织的所有构造步骤接口
/// </summary>
public  interface  IBuider
{
     void  Build<T>() where  T : class , new ();
}

下面给出具体的Builder的缓存实现方案代码

    

public  class  CommonBuilder : IBuider
{
      /// <summary>
      /// 缓存每个对象的具体的构造步骤
      /// </summary>
      private  Dictionary<Type, List<BuildHandler>> steps = null ;
 
     public  void  Build<T>(T ob) where  T : class , new ()
     {
         //从缓存中读取指定类型的项
         List<BuildHandler> handlers = steps[ typeof (T)];
         foreach  (BuildHandler handler in  handlers)
         {
             handler();
         }
     }
}

给出一些获取某个类型内部的所有具有我们的自定义特性标记的MethodInfo列表

       

public  List<MethodInfo> GetMethodInfoList<T>() where  T : class , new ()
{
     //从缓存中读取指定类型的项
     List<MethodInfo> methods = new  List<MethodInfo>();
     T target = new  T();
     MethodInfo[] methodList= typeof (T).GetType().GetMethods();
     BuildAttribute[] attributes = null ;
     foreach  (MethodInfo info in  methodList)
     {
        attributes=  (BuildAttribute[])info.GetCustomAttributes( typeof (BuildAttribute), true );
        if  (attributes.Length > 0)
            methods.Add(info);
     }
     return  methods;
}

获取所有的特性,一般使用这个方法即可获取所有的具有标记该特性的方法列表和相应的步骤:

        

public  List<BuildAttribute> GetBuildAttributeList<T>() where  T : class , new ()
   {
       List<BuildAttribute> attributes = new  List<BuildAttribute>();
       BuildAttribute[] attributeList = null ;
       BuildAttribute attribute = null ;
       foreach  (MethodInfo info in  this .methods)
       {
           //设置特性中要执行的方法
           attributeList = (BuildAttribute[])info.GetCustomAttributes( typeof (BuildAttribute), true );
           if  (attributeList.Length > 0)
           {
               attribute = attributeList[0];
               attribute.BuildHandler = info;
               attributes.Add(attribute);
           }
       }
       //缓存步骤
       steps.Add( typeof (T), attributes);
       return  attributes;
   }

具体的Build中的调用代码实现:

        

public  T Build<T>(T ob) where  T : class , new ()
  {
      List<BuildAttribute> attributeList = GetBuildAttributeList<T>();
      T target= new  T();
      //构造对象的过程
      foreach  (BuildAttribute item in  attributeList)
      {
          item.BuildHandler.Invoke(target, null );
      }
      return  target;
  }

这样我们就完成了一个通用的基于标记的自动发现某个类型的标记方法步骤的通用代码实现,可能大家感觉这样的方式还是挺麻烦的,那么我们还有没有更好的改进方案呢?因为每次打标记我还是感

觉挺麻烦的,而且代码量分布的也比较广泛,我想通过统一配置管理的方式,当然也是可以的,那么我们可以通过下面的方式来进行扩展。

  • 5.3、创建者模式配置文件方式实现

配置文件的方式实现创建者,这个怎么说呢,上面的抽象工厂的模式中,我们主要采用了这样的方式来实现配置的灵活性和扩展性,其实创建者也是一样的,我们来看看配置文件吧,我想

就看配置文件就大概知道了,具体的应用代码了,请看下图,粗略描述了实现的思路:

image

我这里给出配置文件的父子级节点示例:

<? xml  version="1.0" encoding="utf-8" ?>
< Build >
     < BuildClass  name="ClassName" type="ClassType">
         < BuildStep  StepOrder="1" MethodName="MethodName1"/>
         < BuildStep  StepOrder="2" MethodName="MethodName2" />
     </ BuildClass >
     < BuildClass  name="ClassName1" type="ClassType1">
         < BuildStep  StepOrder="1" MethodName="MethodName1"/>
         < BuildStep  StepOrder="2" MethodName="MethodName2" />
     </ BuildClass >
</ Build >

我们这里通过在Build实现中读取配置文件中的所有的步骤,放在字典中。给出示例代码

   

/// <summary>
/// 创建对象组织的所有构造步骤接口
/// </summary>
public  class  Buider : IBuider
{
     private  Dictionary<Type, List<MethodInfo>> steps = null ;
     public  Buider()
     {
         steps = new  Dictionary<Type, List<MethodInfo>>();
         //读取配置文件!
         //将配置文件中的类名和方法名取出,然后通过反射取到这个类型下的所有方法,根据配置中的步骤和方法名添加到
         //步骤列表中,然后缓存到字典中
         steps.Add(Type.GetType( "" ), new  List<MethodInfo>());
     }
     public  T Build<T>() where  T: class , new ()
     {
         T target = new  T();
         //从字典中找到对应的缓存列表,执行构造过程
         List<MethodInfo> list = steps[ typeof (T)];
         //执行构造
         foreach  (MethodInfo info in  list)
         {
             info.Invoke(target, null );
         }
         return  target;
     }
}

通过上面的几步配置就可以完成相应的构建过程,这时候我们的指导者的工作就简单了,就是只是简单的通过使用Build中的通用方法

    

public  class  Director
{
     public  void  Build<T>(IBuider builder) where  T: class , new ()
     {
         builder.Build<T>();
     }
}

只要通过上面的步骤就完成了创建者模式的通用实现方案。

六、创建者模式使用总结

通过上面的给出的几类不同的实现方案我们知道,创建者模式是一个对对象的构建过程“精细化”的构建过程,每个部分的构建可能是变化的,但是对象的组织过程是固定的,通过这种统一的创建方

式,无疑增加了我们设计上的灵活性,当我们在构建复杂对象的时候,我们如果发现每个部分可能都是变化的,并且是多个不同的构建步骤的时候,我们可以考虑使用创建者模式。相比我们之前讲述

的工厂和抽象工厂模式区别还是很大的,我们发现创建者适合这类复杂对象的创建,对于抽象工厂可能就无法完成这样的组装工作,而且创建者模式是把复杂对象的内部创建方法进行调用,组织协调

了对象的各个部分前后顺序的控制。简单的描述创建者就是这样的情况:

image

由于本人水平有限,或者讲述能力有限,表达思路错误或者想法错误,请大家批评指出,如果您有更好的意见或者想法,请提出讨论,欢迎大家提出宝贵意见和建议。

七、系列进度。

      创建型

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

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

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

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

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

        结构型

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

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

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

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

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

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

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

        行为型

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

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

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

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

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

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

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

八、下篇预告。

下篇将会针对原型模式进行讲述,该模式也是创建型模式中很有特点设计模式之一,该 模式是利用现有的一个对象进行克隆的过程产生一个新的对象,当然这里的复制对象可以是2种,深复制和浅复

制,在这个系列的总结中如果您有好的想法或者创意,请提出来,希望大家多提宝贵意见,错误之处还请指出,请大家继续支持。







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


目录
相关文章
|
13天前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
28天前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式
|
20天前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
|
18天前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
|
16天前
|
设计模式 Java
Java设计模式-工厂方法模式(4)
Java设计模式-工厂方法模式(4)
|
2月前
|
设计模式
设计模式-单一职责模式
设计模式-单一职责模式
|
2月前
|
设计模式 XML 存储
【二】设计模式~~~创建型模式~~~工厂方法模式(Java)
文章详细介绍了工厂方法模式(Factory Method Pattern),这是一种创建型设计模式,用于将对象的创建过程委托给多个工厂子类中的某一个,以实现对象创建的封装和扩展性。文章通过日志记录器的实例,展示了工厂方法模式的结构、角色、时序图、代码实现、优点、缺点以及适用环境,并探讨了如何通过配置文件和Java反射机制实现工厂的动态创建。
【二】设计模式~~~创建型模式~~~工厂方法模式(Java)
|
2月前
|
设计模式 XML Java
【一】设计模式~~~创建型模式~~~简单工厂模式(Java)
文章详细介绍了简单工厂模式(Simple Factory Pattern),这是一种创建型设计模式,用于根据输入参数的不同返回不同类的实例,而客户端不需要知道具体类名。文章通过图表类的实例,展示了简单工厂模式的结构、时序图、代码实现、优缺点以及适用环境,并提供了Java代码示例和扩展应用,如通过配置文件读取参数来实现对象的创建。
【一】设计模式~~~创建型模式~~~简单工厂模式(Java)
|
2月前
|
设计模式 uml C语言
设计模式----------工厂模式之简单工厂模式(创建型)
这篇文章详细介绍了简单工厂模式,包括其定义、应用场景、UML类图、通用代码实现、运行结果、实际应用例子,以及如何通过反射机制实现对象创建,从而提高代码的扩展性和维护性。
设计模式----------工厂模式之简单工厂模式(创建型)
|
2月前
|
设计模式 uml
设计模式-------------工厂模式之工厂方法模式(创建型)
工厂方法模式是一种创建型设计模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类,从而实现类的实例化推迟到子类中进行,提高了系统的灵活性和可扩展性。