设计模式初学者笔记:Builder模式
[作者:byeyear Email:byeyear@hotmail.com 首发:cnblogs 转载请注明]
在本文的开头,先森森的鄙视下自己……将Builder模式反反复复读了七八遍,才敢说自己对其有了初步的了解。这比花在Abstract Factory上的时间长多了。如果GoF将Builder模式放在第一个讲,估计我就会把这本书归结成天书直接扔一边了。
Builder模式的关键在于,将“要做什么”与“做出来”分离,将“如何装配”与“完成装配”分离:
Director知道“要做什么”, Builder负责“做出来”;
Director负责指挥, Builder负责实施;
Director负责读懂建筑图纸,Builder负责浇铸钢筋水泥;
Director手里有装配图, Builder执行具体的装配工作。
说得更加极端一点,只有Director才知道要做出来的是什么东西,但不具体动手;而Builder只负责根据Director的指挥去做事情,但它甚至不知道自己做出来的是什么——虽然最终产品是由Builder交付的。从这个角度来说,将Director翻译成“指挥官”,builder翻译成“执行者”似乎更妥帖。
用GoF的代码来做例子:
Maze* MazeGame::CreateMaze(MazeBuilder& builder)
{
// director想要做个新迷宫
// 他们找了个施工队builder // director说,先做个地基吧
// builder就做了个地基
builder.BuildMaze(); // director又让builder做了两个房间
builder.BuildRoom();
builder.BuildRoom(); // director跟builder说还要在两个房间之间打个门洞
builder.BuildDoor(, ); // director说,把你做的东西交给我吧
return builder.GetMaze();
}
过年了,director和builder各自回家。亲戚朋友聚会的时候说起这一年都干了些什么——
director说,我找施工队造了个迷宫,这个迷宫有两个房间和一个门(真够寒酸……);
builder说,我接了个活,造了两个房间,还在两个房间之间打了个洞。天知道这玩意是干嘛用的,那个director准是脑袋秀逗了!
第二年,director准备继续造迷宫,而builder继续在市场上揽活。
director这次另外找了个施工队,新的施工队同样会干打地基、造房子、打门洞这些活,但新施工队造的房子是三角形的,而打出的门洞是半圆的:
{
// 造三角房间和圆门洞的builder
AnotherMazeBuilder builder;
// 开工吧,童鞋们!
CreateMaze((MazeBuilder&)builder);
}
而原来的builder们有了新的东家,新东家造的迷宫布局不太一样,不过同样是由房间和门洞组成:
{
builder.BuildMaze();
builder.BuildRoom();
builder.BuildRoom();
builder.BuildRoom();
builder.BuildRoom(,);
builder.BuildRoom(,);
return Builder.GetMaze();
}
实际上,上面的例子还不是太完善。例如,我们可以将迷宫布局和该迷宫所用房间形状放在文件里(同一个迷宫使用相同的房间形状),而director负责解析文件结构并将任务派遣给builder们。这样,不同的迷宫布局及它们所用房间形状可以通过更换文件实现,而director不变。如果你需要六边形的迷宫房间和三角形的门洞,只要重新实现一个新的builder,然后让director将建造房间、门洞和组装的任务派遣给这个新的builder。这样的例子就更接近于GoF书中所用的RTFReader了。
这里顺便引用下《大话设计模式》一书中的相应例子,那个例子中要求小人不能缺胳膊少腿,但从上文中我们可以看出,Builder模式其实是可以造出断臂维纳斯的:
CreateVenus(PersonBuilder& builder)
{
builder->Prepare();
builder->BuildHead();
builder->BuildBody();
// 断臂的Venus
// builder->BuildArmLeft();
// builder->BuildArmRight();
builder->BuildLegLeft();
builder->BuildLegRight();
return builder->GetPerson();
}
PersonBuilder类实际上并不知道自己build出来的是不是个完整的Person,只是根据Director的要求造出Head,body,……,并组装起来。而造出的到底是人棍还是无头骑士,这个是Director决定的。
[2014.08.01] 当我们创建对话框的时候,是否可考虑builder模式?Director知道对话框上有哪些子窗口,而Builder负责构建这些子窗口并layout之……
设计模式初学者笔记:Builder模式的更多相关文章
- 设计模式初学者笔记:Factory Method模式
如果要选择一种最多人熟悉的Factory Method模式的具体应用,那么就应该是MFC的App/Doc架构了.Factory Method主要在类框架中使用,以解决以下问题:框架必须实例化类,但框架 ...
- 设计模式之笔记--建造者模式(Builder)
建造者模式(Builder) 定义 建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 类图 描述 Builder:定义一个建造者抽象类,以规范产 ...
- 设计模式初学者笔记:Abstract Factory模式
首先啰嗦下创建迷宫所用的Room类.这个类并不直接保存Room四周的构造,而是通过MapSite* _sides[4]这个私有数组成员指向Room四周的构造.那么什么时候将四周构造直接放在Room中, ...
- 设计模式之生成器(Builder)模式
意图 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以表示不同的表示. 适用性 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时. 当构造过程必须允许被构造的对象有不同的表 ...
- C# 设计模式巩固笔记 - 建造者模式
前言 写给自己-贵在坚持.建造者模式不复杂,但是想个形象的例子好难. 介绍-建造者模式 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 实现 建造者模式主要是应对复杂 ...
- Java-马士兵设计模式学习笔记-建造者模式
一.概述 二.代码 1.Animal.java public interface Animal { public void bark(); } 2.Dog.java public class Dog ...
- Java-马士兵设计模式学习笔记-命令模式
一.概述 命令模式 二.代码 1.Client.java public class Client { public void request(Server server){ server.addCom ...
- Java-马士兵设计模式学习笔记-桥接模式
一.概述 1.桥接模式的应用情况:(1)两个维度扩展(2)排列组合 二.代码 1.Gift.java public class Gift { protected GiftImpl giftImpl; ...
- 设计模式之笔记--解释器模式(Interpreter)
解释器模式(Interpreter) 定义 解释器模式(Interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 类图 描述 Expr ...
随机推荐
- 太过亲密往往不好——用non-member,non-friend替换member函数
在前一篇文章,我们提到,使用private来代替public以提高class的封装性.这一篇文章,我们将对接口发起攻势.首先来个简单的例子. class WebBrowser { public: vo ...
- 跟我一起学习ASP.NET 4.5 MVC4.0(一)
跟我一起学习ASP.NET 4.5 MVC4.0(一) 由于上面一个项目使用的是ASP.NET4.0 MVC3.0,在招人的时候发现很多人有听说过MVC,但是却是没用过,对MVC也只是一知半解,最 ...
- java web中的多条件查询
转自:http://blog.csdn.net/xulu_258/article/details/46623317 所谓多条件查询即为用户输入想要查询的条件,然后根据用户输入的条件进行查询. 当用户有 ...
- IIS7.5 与 Tomcat 8整合
IIS需要与Tomcat共用80端口,现在只能通过IIS来转发请求给Tomcat实现,即所谓的整合: 一.下载The Apache Tomcat Connector,下载地址是:http://www. ...
- 基于资源名的MVC权限控制
在程序复杂程度不断上升的过程中,无可避免需要触碰到权限控制,而权限控制又与业务逻辑紧紧相关,市场上出现了大量的权限控制产品,而程序的开发,讲究去繁化简的抽象,在我的开发过程中,逐渐发现程序的权限控制核 ...
- Elasticsearch利用scroll查询获取所有数据
Elasticsearch有两种分页方式,一种是通过from和size条件来实现,但是该方法开销比较大,另一种是利用scroll来实现,通过scroll来实现分页获取所有的数据,下面是利用python ...
- 深入理解uwsgi和gunicorn网络模型
前言: 去年10月份建了一个python技术群,到现在为止人数已经涨到700人了.最一开始我经常在群里回应大家的问题,不管是简单还是困难的,我都会根据自己的经验来交流. 让人新奇的是一些初学者关注最多 ...
- JPush删除别名及回调函数(SWIFT)
JPush(极光)删除别名传空字符串即可,官方回调函数的例子为OC的.用SWIFT其实也差不多. //用户登出后删除别名 APService.setAlias("", callba ...
- NBUT 1224 Happiness Hotel 2010辽宁省赛
Time limit 1000 ms Memory limit 131072 kB The life of Little A is good, and, he managed to get enoug ...
- Python模块 实现过渡性模块重载
本文是在阅读Python 学习手册后 感觉比较不错的一个实现模块重载的一个模块,该模块可以实现对已经加载在运行程序中的模块实现重新加载,并且该模块可以递归的实现对要重新加载的模块内所引用的其它模块的 ...