(http://blog.csdn.net/hguisu/article/details/7518060)

1. 概述

在软件开发的过程中,当遇到一个“复杂的对象”的创建工作,该对象由一定各个部分的子对象用一定的算法构成,由于需求的变化,复杂对象的各个部分经常面临剧烈的变化,但将它们组合在一起的算法相对稳定。

例子1:买肯德基

典型的儿童餐包括一个主食,一个辅食,一杯饮料和一个玩具(例如汉堡、炸鸡、可乐和玩具车)。这些在不同的儿童餐中可以是不同的,但是组合成儿童餐的过程是相同的。


       客户端:顾客,想去买一套套餐(这里面包括汉堡,可乐,薯条),可以有1号和2号两种套餐供顾客选择。
       指导者角色:收银员。知道顾客想要买什么样的套餐,并告诉餐馆员工去准备套餐。
       建造者角色:餐馆员工。按照收银员的要求去准备具体的套餐,分别放入汉堡,可乐,薯条等。
       产品角色:最后的套餐,所有的东西放在同一个盘子里面。

例子2:计算工资:工资的计算一般是:底薪+奖金-税。但底薪分为一级8000、二级6000、三级4000三个等级。根据岗位不同奖金的发放也不一样,管理及日常事务处理岗位(A类)每月根据领导及同事间的评议得分计算奖金,销售岗位(B类)则根据销售额发放提成。税金则根据奖金和底薪的数额进行计算。由此看出该工资的计算方式是比较稳定的构建算法,但对工资的每一部分都会根据不同的情况产生不同的算法,如何将客户端与变化巨烈的底薪、奖金和税金计算方式分离呢,这也比较适合用建造者模式。

2 . 问题

我们如何应对这种变化,如何提供一种“封装机制”来隔离“复杂对象的各个部”的变化,从而保持系统中的“稳定构建算法”而不随需求的变化而变化?

3. 解决方案

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

4. 适用性

在以下情况使用Builder模式

•当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

•当构造过程必须允许被构造的对象有不同的表示时。

5. 结 构

此模式结构如下页上图所示。

6. 构建模式的组成

• 抽象建造者角色(Builder):为创建一个Product对象的各个部件指定抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此角色规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
• 具体建造者(ConcreteBuilder)

1)实现Builder的接口以构造和装配该产品的各个部件。即实现抽象建造者角色Builder的方法。

2)定义并明确它所创建的表示,即针对不同的商业逻辑,具体化复杂对象的各部分的创建

3)  提供一个检索产品的接口

4)   构造一个使用Builder接口的对象即在指导者的调用下创建产品实例

指导者(Director):调用具体建造者角色以创建产品对象的各个部分。指导者并没有涉及具体产品类的信息,真正拥有具体产品的信息是具体建造者对象。它只负责保证对象各部分完整创建或按某种顺序创建。

产品角色(Product):建造中的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产品的接口。

7. 效果

Builder模式的主要效果:

1 ) 它使你可以改变一个产品的内部表示 Builder对象提供给导向器一个构造产品的抽象接口。该接口使得生成器可以隐藏这个产品的表示和内部结构。它同时也隐藏了该产品是如何装配的。因为产品是通过抽象接口构造的,你在改变该产品的内部表示时所要做的只是定义一个新的生成器。

2) 它将构造代码和表示代码分开 Builder模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。客户不需要知道定义产品内部结构的类的所有信息;这些类是不出现在Builder接口中的。每个Concrete Builder包含了创建和装配一个特定产品的所有代码。这些代码只需要写一次;然后不同的Director可以复用它以在相同部件集合的基础上构作不同的Product。

3 ) 它使你可对构造过程进行更精细的控制 Builder模式与一下子就生成产品的创建型模式不同,它是在导向者的控制下一步一步构造产品的。仅当该产品完成时导向者才从生成器中取回它。因此Builder接口相比其他创建型模式能更好的反映产品的构造过程。这使你可以更精细的控制构建过程,从而能更精细的控制所得产品的内部结构。

8. 实现:

指导者:收银员
[php] view plaincopy print?
  1. <?php
  2. /**
  3. * 指导者:收银员
  4. *
  5. */
  6. class DirectorCashier
  7. {
  8. /**
  9. * 收银餐馆员工返回的食物
  10. *
  11. */
  12. public function buildFood(Builder $builder) {
  13. $builder->buildPart1();
  14. $builder->buildPart2();
  15. }
  16. }

抽象建造者:

[php] view plaincopy print?
  1. /**
  2. * 抽象建造者
  3. *
  4. */
  5. abstract class Builder
  6. {
  7. /**
  8. * 创建产品的第一部分
  9. */
  10. public abstract function buildPart1();
  11. /**
  12. *
  13. * 创建产品的第二部分
  14. */
  15. public abstract function buildPart2();
  16. /**
  17. *
  18. *  返回产品
  19. */
  20. public abstract function getProduct();
  21. }

具体建造者类:

[php] view plaincopy print?
  1. /**
  2. * 具体建造者类:餐馆员工,返回的套餐是:汉堡两个+饮料一个
  3. *
  4. */
  5. class ConcreteBuilder1 extends Builder
  6. {
  7. protected $_product = null;//产品对象
  8. function __construct(){
  9. $this->_product = new Product();
  10. }
  11. /**
  12. * 创建产品的第一部分::汉堡=2
  13. */
  14. public  function buildPart1()
  15. {
  16. $this->_product->add('Hamburger',2);
  17. }
  18. /**
  19. *
  20. * 创建产品的第二部分:
  21. */
  22. public  function buildPart2()
  23. {
  24. $this->_product->add('Drink', 1);
  25. }
  26. /**
  27. * 返回产品对象 :
  28. *
  29. */
  30. public function  getProduct()  {
  31. return  $this->_product;
  32. }
  33. }
  34. /**
  35. * 具体建造者类:餐馆员工,汉堡1个+饮料2个
  36. *
  37. */
  38. class ConcreteBuilder2 extends Builder
  39. {
  40. protected $_product = null;//产品对象
  41. function __construct(){
  42. $this->_product = new Product();
  43. }
  44. /**
  45. * 创建产品的第一部分:汉堡
  46. */
  47. public  function buildPart1()
  48. {
  49. $this->_product->add('Hamburger', 1);
  50. }
  51. /**
  52. *
  53. * 创建产品的第二部分:drink=2
  54. */
  55. public  function buildPart2()
  56. {
  57. $this->_product->add('Drink', 2);
  58. }
  59. /**
  60. * 返回产品对象 :
  61. *
  62. */
  63. public function  getProduct()  {
  64. return  $this->_product;
  65. }
  66. }

产品类:

[php] view plaincopy print?
  1. /**
  2. * 产品类
  3. */
  4. class Product
  5. {
  6. public $products = array();
  7. /**
  8. * 添加具体产品
  9. */
  10. public function add($name,  $value) {
  11. $this->products[$name] = $value;
  12. }
  13. /**
  14. * 给顾客查看产品
  15. */
  16. public function showToClient()
  17. {
  18. foreach ($this->products as $key => $v) {
  19. echo $key , '=' , $v ,'<br>';
  20. }
  21. }
  22. }
[php] view plaincopy print?
  1. 客户程序:
[php] view plaincopy print?
  1. <pre name="code" class="php"> //客户程序
  2. class Client
  3. {
  4. /**
  5. * 顾客购买套餐
  6. *
  7. */
  8. public  function buy($type) {
  9. //指导者,收银员
  10. $director  = new DirectorCashier();
  11. //餐馆员工,收银员
  12. $class = new ReflectionClass('ConcreteBuilder' .$type );
  13. $concreteBuilder  = $class->newInstanceArgs();
  14. //收银员组合员工返回的食物
  15. $director->buildFood($concreteBuilder);
  16. //返回给顾客
  17. $concreteBuilder->getProduct()->showToClient();
  18. }
  19. }
  20. //测试
  21. ini_set('display_errors', 'On');
  22. $c = new Client();
  23. $c->buy(1);//购买套餐1
  24. $c->buy(2);//购买套餐1</pre>
  25. <pre></pre>
  26. <pre></pre>
  27. <pre></pre>

9. 建造者模式的优点

首先,建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在导演类中对整体而言可以取得比较好的稳定性。

其次,建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。

10. 建造者模式与工厂模式的区别

我们可以看到,建造者模式与工厂模式是极为相似的,总体上,建造者模式仅仅只比工厂模式多了一个“导演类”的角色。在建造者模式的类图中,假如把这个导演类看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。

与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。

11. 总结

建造者模式与工厂模式类似,他们都是建造者模式,适用的场景也很相似。一般来说,如果产品的建造很复杂,那么请用工厂模式;如果产品的建造更复杂,那么请用建造者模式。

转载于:https://www.cnblogs.com/mimime/p/6078580.html

【转】设计模式(三)建造者模式Builder(创建型)相关推荐

  1. C++设计模式之建造者模式(builder)(创建型)

    软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累. ...

  2. 23天读懂23种设计模式:原型模式(创建型)

    点击上方 蓝字 关注我们 创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建.组合和表示方式. 原型模式目的:用原型实例指定创建对象的种类,并且通过拷贝这些原型创 ...

  3. Android设计模式之建造者模式builder

    今天小编来说一下Android中的一种设计模式--建造者模式Builder 绪论: 那么对于Android初级来说,Builder设计模式可能在我们开发中用过的很少,但是我们可能见过,我们经常用的Al ...

  4. Python 设计模式之建造者模式 Builder Pattern

    #引入建造者模式 肯德基的菜单上有 薯条, 鸡腿,鸡翅,鸡米花,可乐,橙汁,火腿汉堡,至尊虾汉堡,牛肉汉堡 , 鸡肉卷等这些单品,也有很多套餐. 比如 套餐1:鸡翅,至尊虾汉堡,可乐,薯条 套餐2:鸡 ...

  5. UE4 C++设计模式:建造者模式(Builder Pattern)

    目录 描述 套路 使用场景 优缺点 UE4实践 具体复杂产品-门派角色 抽象建造者-角色构造器 具体建造者-纯阳角色构造器 具体建造者-七秀角色构造器 创建指挥者(Director)-角色创建指挥器 ...

  6. 创建型设计模式之建造者模式(Builder)

    结构 意图 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 适用性 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时. 当构造过程必须允许被构造的对象有不 ...

  7. 07、人人都会设计模式:建造者模式--Builder

    PS:转载请注明出处 作者: TigerChain 地址: http://www.jianshu.com/p/300cbb9ee7f2 本文出自 TigerChain 简书 人人都会设计模式 教程简介 ...

  8. 一天一个设计模式之建造者模式(Builder)

    建造者模式,属于创建型模式,其目的在于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 适用情况: • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时. ...

  9. GOF23(3)之建造者模式(创建型模式)

    1.场景 我们需要建造一个比较复杂的产品,如神舟飞船.这个产品创建起来非常的复杂,它肯定是由很多的零件先组成组件,然后组件再组成产品的,那么就会涉及到组件组装的顺序问题. 实际开发中,我们所需要的对象 ...

  10. 设计模式之—建造者模式(Builder)-Java实现

    Builder模式,将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部 表象的产品对象.建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节.建造模式可以 ...

最新文章

  1. HttpUnit学习笔记
  2. SAP QM QE02 修改检验结果,报错 -No characteristics were found–
  3. vs程序生成后找不到exe文件
  4. VIBE复现过程,使用nvidia和libOpenGL.so渲染出错及解决方案
  5. 1.3 xss原理分析与剖析(4)
  6. 2019年嵌入式开发系统详细分析告诉你是否还值得去学习
  7. configure: error: no termcap library found
  8. php 显示当前年月日时分秒,php 获取当前前后年、月、星期、日、时分秒的时间...
  9. gezabo变黑闪退,报错[gazebo_gui-2] process has died
  10. java 内存泄露 书籍_[Java教程]一次艰难的内存泄露排查,BeanUtils 的锅
  11. swfupload 实例 php,文件上传之SWFUpload插件(代码)_php实例
  12. android开发实战-记账本APP(二)
  13. 中正平和的机器人学笔记——2. 机械臂逆运动学(附MATAB代码)
  14. 初中信息技术考试:Python试题及答案
  15. Java之Joda工具包处理时间的7点总结分享
  16. php加cnzz,Vue单页面中添加cnzz统计
  17. PHP读取word文档 导入word文档
  18. 金庸走过,留给马云和阿里巴巴一个“江湖”
  19. curl打开网页403或者302的解决方法(详细总结)
  20. 实战 Vue 之生命周期钩子函数执行顺序

热门文章

  1. 转:FAMI上的满分游戏
  2. MessageDigest 类的用法
  3. 硬件设计论坛_零基础学硬件工程师到哪里去培训 上EDA365电子论坛
  4. 6款Windows超好用的ZIP密码解锁软件
  5. arduino如何驱动1602显示器?(使用arduino内置LiquidCrystal库)
  6. Setup Factory安装及程序安装包制作教程
  7. Firefox在win10与win11系统上账号不同步的解决办法
  8. 如何批量生成视频二维码
  9. XMPP即时通讯基础知识
  10. Android的第一行代码