意图

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

场景

在电脑城装机总有这样的经历。我们到了店里,先会有一个销售人员来询问你希望装的机器是怎么样的配置,他会给你一些建议,最终会形成一张装机单。和客户确定了装机配置以后,他会把这张单字交给提货的人,由他来准备这些配件,准备完成后交给装机技术人员。技术人员会把这些配件装成一个整机交给客户。

不管是什么电脑,它总是由CPU、内存、主板、硬盘以及显卡等部件构成的,并且装机的过程总是固定的:

l         把主板固定在机箱中

l         把CPU安装到主板上

l         把内存安装到主板上

l         把硬盘连接到主板上

l         把显卡安装到主板上

但是,每台兼容机的部件都各不相同的,有些配置高一点,有些配置低一点,这是变化点。对于装机技术人员来说,他不需要考虑这些配件从哪里来的,他只需要把他们组装在一起了,这是稳定的装机流程。要把这种变化的配件和稳定的流程进行分离就需要引入Builder模式。

示例代码

using System;

using System.Collections.Generic;

using System.Text;

using System.Reflection;

namespace BuilderExemple

{

    classProgram

    {

        staticvoid Main(string[] args)

        {

            ComputerFactory factory = newComputerFactory();

            ComputerBuilder office = newOfficeComputerBuilder();

            factory.BuildComputer(office);

            office.Computer.ShowSystemInfo();

            ComputerBuilder game = newGameComputerBuilder();

            factory.BuildComputer(game);

            game.Computer.ShowSystemInfo();

        }

    }

    classComputerFactory

    {

        publicvoid BuildComputer(ComputerBuilder cb)

        {

            Console.WriteLine();

            Console.WriteLine(">>>>>>>>>>>>>>>>>>Start Building " + cb.Name);

            cb.SetupMainboard();

            cb.SetupCpu();

            cb.SetupMemory();

            cb.SetupHarddisk();

            cb.SetupVideocard();

            Console.WriteLine(">>>>>>>>>>>>>>>>>>Build " + cb.Name + " Completed");

            Console.WriteLine();

        }

    }

    abstractclassComputerBuilder

    {

        protectedstring name;

        publicstring Name

        {

            get { return name; }

            set { name = value; }

        }

        protectedComputer computer;

        publicComputer Computer

        {

            get { return computer; }

            set { computer = value; }

        }

        public ComputerBuilder()

        {

            computer = newComputer();

        }

        publicabstractvoid SetupMainboard();

        publicabstractvoid SetupCpu();

        publicabstractvoid SetupMemory();

        publicabstractvoid SetupHarddisk();

        publicabstractvoid SetupVideocard();

    }

    classOfficeComputerBuilder : ComputerBuilder

    {

        public OfficeComputerBuilder()

        {

            name = "OfficeComputer";

        }

        publicoverridevoid SetupMainboard()

        {

            computer.Mainboard = "Abit升技LG-95C 主板(Intel 945GC芯片组/LGA 775/1066MHz) ";

        }

        publicoverridevoid SetupCpu()

        {

            computer.Cpu = "Intel 英特尔赛扬D 336 (2.8GHz/LGA 775/256K/533MHz)  ";

        }

        publicoverridevoid SetupMemory()

        {

            computer.Memory = "Patriot博帝DDR2 667 512MB 台式机内存";

        }

        publicoverridevoid SetupHarddisk()

        {

            computer.Harddisk = "Hitachi日立SATAII接口台式机硬盘(80G/7200转/8M)盒装";

        }

        publicoverridevoid SetupVideocard()

        {

            computer.Videocard = "主板集成";

        }

    }

    classGameComputerBuilder : ComputerBuilder

    {

        public GameComputerBuilder()

        {

            name = "GameComputer";

        }

        publicoverridevoid SetupMainboard()

        {

            computer.Mainboard = "GIGABYTE技嘉GA-965P-DS3 3.3 主板(INTEL P965 东莞产)" ;

        }

        publicoverridevoid SetupCpu()

        {

            computer.Cpu = "Intel 英特尔酷睿E4400 (2.0GHz/LGA 775/2M/800MHz)盒装";

        }

        publicoverridevoid SetupMemory()

        {

            computer.Memory = "G.SKILL 芝奇F2-6400CL5D-2GBNQ DDR2 800 1G*2台式机内存";

        }

        publicoverridevoid SetupHarddisk()

        {

            computer.Harddisk = "Hitachi日立SATAII接口台式机硬盘(250G/7200转/8M)盒装";

        }

        publicoverridevoid SetupVideocard()

        {

            computer.Videocard = "七彩虹逸彩GT-GD3 UP烈焰战神H10 显卡(GeForce 8600GT/256M/DDR3)支持HDMI!";

        }

    }

    classComputer

    {

        privatestring videocard;

        publicstring Videocard

        {

            get { return videocard; }

            set { videocard = value; }

        }

        privatestring cpu;

        publicstring Cpu

        {

            get { return cpu; }

            set { cpu = value; }

        }

        privatestring mainboard;

        publicstring Mainboard

        {

            get { return mainboard; }

            set { mainboard = value; }

        }

        privatestring memory;

        publicstring Memory

        {

            get { return memory; }

            set { memory = value; }

        }

        privatestring harddisk;

        publicstring Harddisk

        {

            get { return harddisk; }

            set { harddisk = value; }

        }

        publicvoid ShowSystemInfo()

        {

            Console.WriteLine("==================SystemInfo==================");

            Console.WriteLine("CPU:" + cpu);

            Console.WriteLine("MainBoard:" + mainboard);

            Console.WriteLine("Memory:" + memory);

            Console.WriteLine("VideoCard:" + videocard);

            Console.WriteLine("HardDisk:" + harddisk);

        }

    }

}

代码执行结果如下图:

 

代码说明

l         ComputerFactory是建造者模式的指导者。指导者做的是稳定的建造工作,假设它就是一个技术人员,他只是在做按照固定的流程,把配件组装成计算机的重复劳动工作。他不知道他现在组装的是一台游戏电脑还是一台办公用电脑,他也不知道他往主板上安装的内存是1G还是2G的。呵呵,看来是不称职的技术人员。

l         ComputerBuilder是抽象建造者角色。它主要是用来定义两种接口,一种接口用于规范产品的各个部分的组成。比如,这里就规定了组装一台电脑所需要的5个工序。第二种接口用于返回建造后的产品,在这里我们没有定义抽象方法,反正建造出来的总是电脑。

l         OfficeComputerBuilder和GameComputerBuilder是具体的建造者。他的工作就是实现各建造步骤的接口,以及实现返回产品的接口,在这里后者省略了。

l         Computer就是建造出来的复杂产品。在代码中,我们的各种建造步骤都是为创建产品中的各种配件服务的,Computer定义了一个相对具体的产品,在应用中可以把这个产品进行比较高度的抽象,使得不同的具体建造者甚至可以建造出完全不同的产品。

l         看看客户端的代码,用户先是选择了一个具体的Builder,用户应该很明确它需要游戏电脑还是办公电脑,但是它可以对电脑一无所知,由销售人员给出一个合理的配置单。然后用户让ComputerFactory去为它组装这个电脑。组装完成后ComputerFactory开机,给用户验收电脑的配置是否正确。

l         你或许觉得ComputerBuilder和是抽象工厂模式中的抽象工厂角色差不多,GameComputerBuilder又像是具体工厂。其实,建造者模式和抽象工厂模式的侧重点不同,前者强调一个组装的概念,一个复杂对象由多个零件组装而成并且组装是按照一定的标准射顺序进行的,而后者强调的是创建一系列产品。建造者模式适用于组装一台电脑,而抽象工厂模式适用于提供用户笔记本电脑、台式电脑和掌上电脑的产品系列。

何时采用

l         从代码角度来说, 如果你希望分离复杂类型构建规则和类型内部组成,或者希望把相同的构建过程用于构建不同类型的时候可以考虑使用建造者模式。

l         从应用角度来说, 如果你希望解耦产品的创建过程和产品的具体配件,或者你希望为所有产品的创建复用一套稳定并且复杂的逻辑的时候可以考虑使用建造者模式。

实现要点

l         对象的构建过程由指导者完成,具体的组成由具体建造者完成,表示与构建分离。

l         建造者和指导者是建造者模式的关键点,如果进行合并或省略就可能会转变到模版方法模式。

l         如果对象的建造步骤是简单的,并且产品拥有一致的接口可以转而使用工厂模式。

注意事项

l         返回产品的方法是否必须,是否一定要在抽象建造者中有接口根据实际情况而定。如果它们有统一的接口可以在抽象建造者中体现这个抽象方法,如果没有统一的接口(比如,生产毫无关联的产品)则可以在具体建造者中各自实现这个方法,如果创建的产品是一种产品,那么甚至可以省略返回产品的接口(本文的例子就是这样)。

原文链接:http://www.cnblogs.com/lovecherry/archive/2007/10/07/915986.html

c#设计模式-建造者模式相关推荐

  1. Python设计模式-建造者模式

    Python设计模式-建造者模式 代码基于3.5.2,代码如下; #coding:utf-8 #建造者模式 class Burger():name = ""price = 0.0d ...

  2. 说说设计模式~建造者模式(Builder)

    建造者模式是我的"设计模式"里创建型模式里的最后一篇,这种模式在实现中,很多架构都用到了,如MVC,MVP,MVVM,它们都是有建造者模式的精髓的,即,创建与表现分享,我们的MVC ...

  3. 设计模式 建造者模式_设计模式:建造者

    设计模式 建造者模式 有时需要在应用程序中创建一个复杂的对象. 一种解决方案是Factory模式,另一种是Builder设计模式. 在某些情况下,您甚至可以结合使用这两种模式. 但是在本文中,我想研究 ...

  4. 设计建造者模式java代码,Java设计模式-建造者模式

    定义 Separate the construction of a complex object from its representation so that the sameconstructio ...

  5. python创造者_python 设计模式-建造者模式

    问题:在上一篇python设计模式:抽象工厂模式中,我们尝试用抽象工厂模式规范化了 Pizza 原材料的供应以及 Pizza 的创建.但是我们忽略了一个问题,那就是每种 Pizza 的烘焙时间依赖于生 ...

  6. java设计模式-建造者模式

    概念:使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. ...

  7. 设计模式-建造者模式(转自:http://www.cnblogs.com/cbf4life/archive/2010/01/14/1647710.html)...

    11.1 变化是永恒的 又是一个周三,快要下班了,老大突然拉住我,喜滋滋地告诉我:"牛叉公司很满意我们做的模型,又签订了一个合同,把奔驰.宝马的车辆模型都交给我们公司制作了,不过这次又额外增 ...

  8. 大话设计模式—建造者模式

    建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 一个 Builder 类会一步一步构造最 ...

  9. 我的Java设计模式-建造者模式

    在未上大学之前,一直有个梦想"I have a dream!",就是能成为一位汽车工程师,一直幻想着开着自己设计的汽车飞奔在公路上,迷倒了万千少女.咳咳~~虽然现在没实现我的dre ...

  10. Java常用设计模式————建造者模式

    引言 建造者模式(Builder Pattern)使用多个简单对象一步一步构建成一个复杂的对象.这种类型的设计模式属于建造型模式,它提供了一种创建对象的最佳方式. 一个Builder会一步步构建最终的 ...

最新文章

  1. 最牛程序员,雷军年度演讲:最好的投资,就是投资自己
  2. python数值运算实例_Python矩阵常见运算操作实例总结
  3. c#数组赋初值_JavaScript数组的声明、访问和遍历方法
  4. Design Pattern Strategy C
  5. jquery 毫秒转换成日期_jQuery Datepicker – 如何将日期格式化为纪元时间戳(以秒为单位,而不是毫秒)...
  6. linux 系统权限 数字含义
  7. #ifndef.#define, #endif 的用法
  8. 2021 整理的最全学习资源,送给每一个努力着的人
  9. 如何创建_如何创建自己的微信圈子?圈子创建运营指南
  10. 数据结构与算法(C#版)第二章 C#语言与面向对象技术(中)V1.0
  11. java struts2 mvc_struts2的MVC模式
  12. SVN工作笔记001---svn删除已经上传的文件
  13. 敏捷开发与测试(面试话题之一)
  14. 聊一聊FPGA的片内资源相关知识
  15. firefox ie 鼠标事件 坐标 兼容问题
  16. #425[div2]
  17. [Vue CLI 3] 环境变量和模式配置实践与源码分析
  18. 使用代码控制小米智能插座
  19. Java修改文件夹名称
  20. word流程图怎么做虚线框_word虚线框怎么打 word中目录虚线怎么打?

热门文章

  1. python进程、线程、协程
  2. Condition类必须配合Mutex使用,why?
  3. python decode unicode encode
  4. 【HTML 初学】1、HTML元素
  5. MySQL 去除重复的方法
  6. VS2010/MFC编程入门之四(MFC应用程序框架分析)
  7. 计算机专业大学生每天睡多久,大学生睡眠时间最少的10个专业!是你的专业吗?...
  8. kfaka storm写入mysql_flume+kafka+storm+mysql架构设计
  9. phpmyadmin 4.8.1 Remote File Inclusion(CVE-2018-12613)远程文件包含漏洞复现
  10. 禁止ensp弹出提示