设计模式初学者笔记: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 ...
随机推荐
- cas AuthenticationFilter
AuthenticationFilter *** 这个类的作用:判断是否已经登录,如果没有登录则根据配置的信息来决定将跳转到什么地方 *** casServerLoginUrl:定义cas 服务器的登 ...
- linux command dialog
Linux command dialog [Purpose] Learning how to use dialog commad, do man-machine interaction ...
- bzoj1083
题解: 简单最小生成树 代码: #include<bits/stdc++.h> using namespace std; #define y1 ____y1 ; int z[N],f[N] ...
- EClassNotFound
---------------------------Debugger Exception Notification---------------------------Project Project ...
- js前台数据校验
1.脚本 Validator = { exp:{ numWord:/^[A-Za-z0-9]+$/, //数字或字母 numWordM:/^[\-]*[A-Za-z0-9]+$/, //数字或字母可为 ...
- Linux运维学习笔记-TCP三次握手和四次挥手
TCP三次握手: TCP四次挥手:
- CentOS7安装OpenStack(Rocky版)-09.安装Cinder存储服务组件(控制节点)
本文分享openstack的Cinder存储服务组件,cinder服务可以提供云磁盘(卷),类似阿里云云盘 ----------------------- 完美的分隔线 -------------- ...
- 共享仓库,远程仓库,多人协作,github操作
1.共享仓库: 创建共享仓库 1.创建文件夹 mkdir file 2.设置文件夹属主 chown tarena:tarena file 3.将该文件夹设置为可共享的git仓库 cd file git ...
- 定义一组抽象的 Awaiter 的实现接口,你下次写自己的 await 可等待对象时将更加方便
我在几篇文章中都说到了在 .NET 中自己实现 Awaiter 情况.async / await 写异步代码用起来真的很爽,就像写同步一样.然而实现 Awaiter 没有现成的接口,它需要你按照编译器 ...
- Hibernate4获取sessionFactory
/** * Location of hibernate.cfg.xml file. * Location should be on the classpath as Hibernate uses * ...