介绍

本文讨论生成器设计模式,讨论该模式什么情况下使用,怎么实现。并且。最后会有一个简单的生成器模式的实现。

背景

当我们的程序需要创建一个对象。而这个对象必须由很多不同的对象来构造的时候。为了构造最后的对象。我们不得不组合那些部分对象。最后我们会发现我们的代码被各种各样的部分对象的细节所弄的难以理解

为了说明上面的情况。我们做一个手机生产制造系统的例子。假定我们我们有一个已经安装在手机供应商那块的一个系统。现在供应商系那个要根据一些参数来创造一个新手机。比如触屏,操作系统,电池等。如果我们已经有了这些部分的对象,那么上述部分的任意组合将会导致客户端代码复杂难以管理。比如决定生产哪种手机的模块。

生成器模式目的就是解决上述问题的。GoF定义生成器模式如下:

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

这个定义意味着我们不得不设计这个系统。通过一种客户端仅仅定义参数,而生成器则接管创建复杂对象 的方式。我们看一下生成器模式的类图。

然后看看上图中的每一个类都表示什么

ConcreteBuilder: 创建复杂产品的具体类.将会知道他已经创建的Product(产品),也就是他已经装配了的Product, 客户端通过该类得到Product对象.

Builder: 创建Product的接口

Director: 客户端代码,定义了哪些部分应该被组合在一起来创建具体的Product

Product: 这是通过组合很多部分创建的对象

使用代码

我们现在跟随上述的定义,然后试着去实现一个基本的生成器模式

我们先在合适的地方定义Product的不同部分,我们简单的定义一些枚举类型,那么我们就可以通过组合不同的部分创建Product了。

// 一些helper枚举定义各种零件public enum ScreenType{ScreenType_TOUCH_CAPACITIVE,ScreenType_TOUCH_RESISTIVE,ScreenType_NON_TOUCH};public enum Battery{MAH_1000,MAH_1500,MAH_2000};public enum OperatingSystem{ANDROID,WINDOWS_MOBILE,WINDOWS_PHONE,SYMBIAN};public enum Stylus{YES,NO};

然后,我们看一下Product类,我们需要有一个可以通过装配创建的Product类,这里我们定义一个MobilePhone类,也就是概念里的Product类了。

// 这是 "Product" 类class MobilePhone{// 不同部分的字段string phoneName;      ScreenType phoneScreen;Battery phoneBattery;OperatingSystem phoneOS;Stylus phoneStylus;public MobilePhone(string name){phoneName = name;}//公有属性访问这些部分public string PhoneName{get { return phoneName; }           }public ScreenType PhoneScreen{get { return phoneScreen; }set { phoneScreen = value; }}       public Battery PhoneBattery{get { return phoneBattery; }set { phoneBattery = value; }}       public OperatingSystem PhoneOS{get { return phoneOS; }set { phoneOS = value; }}      public Stylus PhoneStylus{get { return phoneStylus; }set { phoneStylus = value; }}// 显示手机相关信息的方法public override string ToString(){return string.Format("Name: {0}\nScreen: {1}\nBattery {2}\nOS: {3}\nStylus: {4}",PhoneName, PhoneScreen, PhoneBattery, PhoneOS, PhoneStylus);}}

既然我们已经有了Product类,我们来创建Builder吧。Builder类应该提供一些方法可以手机的任何部分。这样我们创建IPhoneBuilder ,也就是概念里的Builder,然后看代码:

// 这是 "Builder" 类interface IPhoneBuilder{void BuildScreen();void BuildBattery();void BuildOS();void BuildStylus();MobilePhone Phone { get;}}

现在我们的Builder接口也准备好了。下一步就是创建ConcreteBuilder了。我们假定供应商事项要一个android手机和一个WP手机。我们就需要两个ConcreteBuilder了。AndroidPhoneBuilder 和  WindowsPhoneBuilder. 在这两个Builder里。我们可以指定每个手机需要的零件类型
// 这是 "ConcreteBuilder" 类class AndroidPhoneBuilder : IPhoneBuilder{MobilePhone phone;public AndroidPhoneBuilder(){phone = new MobilePhone("Android Phone");}#region IPhoneBuilder Memberspublic void BuildScreen(){phone.PhoneScreen = ScreenType.ScreenType_TOUCH_RESISTIVE;}public void BuildBattery(){phone.PhoneBattery = Battery.MAH_1500;}public void BuildOS(){phone.PhoneOS = OperatingSystem.ANDROID;}public void BuildStylus(){phone.PhoneStylus = Stylus.YES;}// 返回创建的手机对象public MobilePhone Phone{get { return phone; }}#endregion}

//这是 "ConcreteBuilder" 类class WindowsPhoneBuilder : IPhoneBuilder{MobilePhone phone;public WindowsPhoneBuilder(){phone = new MobilePhone("Windows Phone");}#region IPhoneBuilder Memberspublic void BuildScreen(){phone.PhoneScreen = ScreenType.ScreenType_TOUCH_CAPACITIVE;}public void BuildBattery(){phone.PhoneBattery = Battery.MAH_2000;}public void BuildOS(){phone.PhoneOS = OperatingSystem.WINDOWS_PHONE;}public void BuildStylus(){phone.PhoneStylus = Stylus.NO;}//返回创建的手机对象public MobilePhone Phone{get { return phone; }}#endregion}

最后我们来创建Director类,我们创建的Director类将会有一个组合函数接受一个IPhoneBuilder 参数,然后调用各自ConcreteBuilder内部的对应方法

// 这是"Director" 类class Manufacturer{public void Construct(IPhoneBuilder phoneBuilder){phoneBuilder.BuildBattery();phoneBuilder.BuildOS();phoneBuilder.BuildScreen();phoneBuilder.BuildStylus();}}

现在我们已经以标准的生成器模式封装了生产复杂Products的方法。现在我们看一下客户端要创建一个Product的时候有多简单。

class Program{static void Main(string[] args){// 首先创建Director
Manufacturer newManufacturer = new Manufacturer();// 然后创建 Builder
IPhoneBuilder phoneBuilder = null;// 创建一个Android手机吧
phoneBuilder = new AndroidPhoneBuilder();newManufacturer.Construct(phoneBuilder);Console.WriteLine("A new Phone built:\n\n{0}", phoneBuilder.Phone.ToString());// 再创建一个WP手机
phoneBuilder = new WindowsPhoneBuilder();newManufacturer.Construct(phoneBuilder);Console.WriteLine("A new Phone built:\n\n{0}", phoneBuilder.Phone.ToString());}}

现在啊,我们如果还要创建更多的对象,仅仅再需要一个ConcreteBuilder类,其他的代码一点都不会动。客户端代码也更容易来创建复杂Product了。我们看看程序输出。

最后看一下我们通过生成器模式写的程序的类图。

Demo下载

Builder Pattern

许可

本文包括源代码和文件在CPOL下授权

原文地址:Understanding-and-Implementing-Builder-Pattern-in

著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

转载于:https://www.cnblogs.com/lazycoding/archive/2012/10/08/2715088.html

[原译]理解并实现生成器模式相关推荐

  1. 初识、理解生成器模式

    声明:这部分是号主学习"研磨设计模式"的笔记以及部分思考. 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 什么意思呢?可以简单理解为:按照同一过 ...

  2. 23种设计模式(4)-生成器模式

    定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.生成器模式利用一个导演者对象和具体建造者对象一个一个地建造出所有的零件,从而建造出完整的对象. 四个要素: Build ...

  3. Builder生成器模式

    这次来学习另一个创建型设计模式:Builder生成器模式. GOF对Builder模式的定义 (1)意图 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. (2)适用性 1. ...

  4. 建造者模式 生成器模式 创建型 设计模式(五)

    建造者模式 Builder 也叫做生成器模式 在正式开始建造者模式之前,先回顾下抽象工厂模式 本人的所有系列文章都是自己学习的记录过程,均有比较严格的先后顺序,如果不清楚抽象工厂模式可以先往前翻翻 从 ...

  5. 设计模式(三):生成器模式

    这是设计模式系列文章的第三篇 之前两篇的阅读效果不是很好,我一度怀疑这种题材的文章不受大家欢迎,直到前两天我面试了一个小姐姐... 面试过程中和小姐姐聊起她在上家公司做过的项目,其中有一个功能,根据小 ...

  6. 设计模式之十生成器模式

    概念 生成器模式的核心是当构建生成一个对象的时候,这个对象一般比较复杂.需要包含多个步骤,虽然每个步骤具体的实现不同,但是都遵循一定的流程与规则 .建造模式是将复杂的内部创建封装在内部,对于外部调用的 ...

  7. C#设计模式 之 生成器模式

    C#设计模式 之 生成器模式 一,意图 二,动机 三,结构 四,优缺点 五,应用场景 六,代码实现 别名:建造者模式.Builder 一,意图   将一个复杂的对象的构建与其表示相分离,使得同样的构建 ...

  8. 研磨设计模式 之 生成器模式(Builder)2 ——跟着cc学设计系列

    8.2  解决方案 8.2.1  生成器模式来解决 用来解决上述问题的一个合理的解决方案就是生成器模式.那么什么是生成器模式呢? (1)生成器模式定义 (2)应用生成器模式来解决的思路 仔细分析上面的 ...

  9. Java建造者模式(生成器模式)

    基本介绍: 建造者模式又叫生成器模式,是一种对象构建模式.它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象 建造者模式是一步一步建造一个复杂 ...

最新文章

  1. wxPython:Python首选的GUI库 | CSDN博文精选
  2. [解决方案]SystemError: Parent module ‘‘ not loaded, cannot perform relative import的解决方案
  3. 实现对文本的简单one-hot编码
  4. mysql慢日志优化_Mysql优化-慢sql日志
  5. 工程中选择数据结构和算法的依据
  6. JS高效数据存取指南
  7. 尚学堂-马士兵-专题-正则表达式
  8. koa2 从入门到进阶之路 (七)
  9. android edittext不可复制_【EditText】Android设置EditText不可编辑 | 学步园
  10. NMEA-0183 协议
  11. 【Linux-Windows】海康网络相机开启ONVIF协议
  12. 好用的图吧工具云资源
  13. 切换IP软件,切换电脑手机IP如此简单
  14. 编程语言之scala基础
  15. iOS 送审浅谈:1.4.1、2.1、2.5.2、2.5.4、4.2.3、5.2.5
  16. python扫雷_python做扫雷
  17. python考研人数数据分析统计服_2019年考研统计数据出炉:往届生考研人数占比48.23%...
  18. python通过ip获取mac地址_Python3根据IP地址获取MAC地址
  19. 笑傲江湖之精忠报国,终于做完了
  20. 机器学习深度学习高阶内容系列-kaggle广告点击欺诈识别实战

热门文章

  1. java 随机生成常用汉字_Java随机生成中文汉字
  2. 查看mali ddk 版本_2019年CPU排行榜,阅读文章查看你的手机CPU还在线上吗
  3. php in_array 遍历,in_array大数组查询性能问题
  4. mysql 3.6.4_TOMCAT5+MYSQL5+JIRA3.6.4配置说明
  5. SpringBoot如何使用策略模式干掉if else
  6. 网络安全模型_基于TCM的网络安全访问模型
  7. vonr信令流程_SA EPS FallBack重要信令节点
  8. python解压zip文件_python-29 python解压压缩包的几种方法
  9. PHP代理模式Proxy Mode
  10. 为什么在notebook里面还是显示torch_torch.utils.cpp_extension对c++/cuda进行拓展