c++设计模式系列----builder模式
看了好几处关于builder模式的书和博客,总感觉不是很清楚,感觉不少书上的说的也不是很准确。最后还是看回圣经《设计模式》。看了好久终于感觉明白了一点了。
意图:
builder模式提出的目的就是为了解决将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不的表示的问题。
我们来看一个例子:
假设我们要画一些人,例如游戏里面的各类人。一般情况下,人有头,手,腿。但是在游戏里面,人可能没有手,也可能不止两只手。即所谓的三头六臂。如下:
那么,在这种情况下应该怎么去生产这些人?
一开始可能会用这个思路:抽象出一个人的基类,然后不同的人继承自这个基类得到一系列的子类。
这个方法有很多缺点:
1、首先很明显的一点是:不同类型的人差别极大,因为人不是都相同的手相同的腿等,以至于很难抽象出共同点。所以抽象出一个基类本身就不现实。
2、利用这种通过继承产生不同人的方法会造成子类的泛滥,比如每多一只手就要多一个子类,造成代码的可拓展性问题,管理问题等。
那么就要用到下面说的builder模式。
builder模式的适用性:
在以下情况使用builder模式
• 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
• 当构造过程必须允许被构造的对象有不同的表示时。
我们注意,builder模式有两个要注意的点,一个是创建复杂对象的算法独立于对象的组成部分以及它们的装配方式。一个是被构造的对象有不同的表示。但我们不能被“复杂对象”所误导,并不是说将复杂对象进行封装就是builder模式了。
我们先来看看模式的结构图:
其中各部分的作用为:
• Builder:
为创建一个Product对象的各个部件指定抽象接口。
• ConcreteBuilder
实现Builder的接口以构造和装配该产品的各个部件。
定义并明确它所创建的表示。
提供一个检索产品的接口。
• Director
构造一个使用Builder接口的对象。
•Product
表示被构造的复杂对象。ConcreteBuilder 创建该产品的内部表示并定义它的装配过程。
包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
也就是说,导向器决定构造一个product的算法,比如构造一个人,导向器就决定他的构造顺序:
1、addHead(); 2、addArm(); 3、addArm(); 4、addArm(); 5、addLeg(); 6、addLeg();
然后导向器通过调用builder的接口来实现具体构造。这样就实现了创建复杂对象的算法和对象的组成部分以及它们的装配方式的分离。
也就是说,builder模式要得到Product并不是通过concreteBuilder一步得到的,它是通过在导向器Director所列出的方法顺序下一步步进行构造得到。并在最后一步后得到一个最终的产品。
我们来看看Director和ConcreteBuilder的协作过程:
其中getResult()方法是得到构造好的实例对象。
使用builder模式的效果如下:
1、Builder对象提供给导向器的抽象接口的具体实现是在Builder内部,那么在改变接口内部的具体实现的时候就不会对导向器使用接口产生影响。它隐藏了产品是如何装配的。另外,因为Builder的抽象接口是一定的,那么你在改变产品的内部结构的时候只需要定义一个新的生成器CuncreteBuilder。然后使用这个生成器去装配产品即可。
2、它将构造代码和表示代码分开,builder模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。客户不需要知道定义产品内部的结构的类的所有信息。这些类是不出现在builder接口中的。每个ConcerteBuilder包含了创建和装配一个特定产品的所有代码。这些代码只需要写一次,然后不同的Director可以复用它以在相同的部件集合的基础上构作不同的Product。
3、它使你可对构造过程进行更精细的控制。Builder模式与一下子就生成产品的创建型模式不同,他是在Director的控制下一步步构造产品。仅当产品构造完成后才从生成器取回它。因此Builder接口相比其他创建型模式能更好地反应产品构造过程。这使你能更精细地控制构建过程,从而能更精细地控制所得产品的内部结构。
那么根据上述画出开始时的问题的builder模式的解决方案的结构图如下:
根据图就不难写出代码了。
值得注意的是,1、产品Product没有抽象类 通常情况下,由具体生成器生成的产品,它们的表示相差很大,以至于给不同的产品以公共父类没有什么。
2、在Builder中缺省的方法为空。在C++中,生成方法故意不声明为纯虚函数,而是把它们定义为空方法,这使得客户可以只重定义他们所感兴趣的操作。
c++设计模式系列----builder模式的更多相关文章
- 设计模式:Builder模式
设计模式:Builder模式 一.前言 今天我们讨论一下Builder建造者模式,这个Builder,其实和模板模式非常的像,但是也有区别,那就是在模板模式中父类对子类中的实现进行操作,在父类之 ...
- Java设计模式之builder模式
Java设计模式之builder模式 今天学mybatis的时候,知道了SQLSessionFactory使用的是builder模式来生成的.再次整理一下什么是builder模式以及应用场景. 1. ...
- Java设计模式-建造者(Builder)模式
目录 由来 使用 1. 定义抽象 Builder 2. 定义具体 Builder类 3. 定义具体 Director类 4. 测试 定义 文字定义 结构图 优点 举例 @ 最近在看Mybatis的源码 ...
- [转]C++设计模式:Builder模式
Builder模式要解决的问题是,当我们要创建很复杂的对象时,有时候需要将复杂对象的创建过程和这个对象的表示分离开来.由于在每一步的构造过程中可以映入不同参数,所以步骤相同但是最后的对象却不一样.也就 ...
- 设计模式之Builder模式
一.感性认识 二.Builder模式 1.定义 一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.即构建过程相同,但是子部件却不相同. 2.结构说明 Builder: 创建者接口 ...
- Java设计模式--Java Builder模式
1.Java Builder模式主要是用一个内部类去实例化一个对象,避免一个类出现过多构造函数,而且构造函数如果出现默认参数的话,很容易出错. public Person(String name) P ...
- PHP设计模式系列 - 外观模式
外观模式 通过在必需的逻辑和方法的集合前创建简单的外观接口,外观设计模式隐藏了调用对象的复杂性. 外观设计模式和建造者模式非常相似,建造者模式一般是简化对象的调用的复杂性,外观模式一般是简化含有很多逻 ...
- 《Android源码设计模式》--Builder模式
No1: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 No2: 在Android源码中,最常用到的Builder模式就是AlertDialog.Builder No3: ...
- akka设计模式系列-While模式
While模式严格来说是while循环在Akka中的合理实现.while是开发过程中经常用到的语句之一,也是绝大部分编程语言都支持的语法.但while语句是一个循环,如果循环条件没有达到会一直执行wh ...
随机推荐
- 【bzoj5008】方师傅的房子 计算几何
题目描述 给出一个凸多边形,多次询问某个点是否在这个凸多边形的内部,强制在线. 输入 第一行一个数n,接下来n行,每行两个整数x,y.输入按照逆时针顺序输入一个凸包. 接下来一个数m,最后有m行, ...
- 【bzoj2502】清理雪道 有上下界最小流
题目描述 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞 ...
- CF97B:Superset——题解
http://codeforces.com/problemset/problem/97/B 题目大意:给n个点,添加一些点,使得任意两个点: 1.在同一条线上 2.以它们为顶点构成的矩形上有其他点. ...
- BZOJ1492: [NOI2007]货币兑换Cash 【dp + CDQ分治】
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MB Submit: 5391 Solved: 2181 [Submit][S ...
- HDU 3277 最大流+二分
Marriage Match III Time Limit: 10000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- Qt ------ 内存回收机制、new对象的回收
写在前面的总结: 建议:对于不能指定父对象的对象(对象通过moveToThread()移入其他线程.没有继承QObject的类产生的对象),在其他线程通过deleteLater()内存回收,其他通过指 ...
- React Mixin
为什么使用 Mixin ? React为了将同样的功能添加到多个组件当中,你需要将这些通用的功能包装成一个mixin,然后导入到你的模块中. 可以说,相比继承而已,React更喜欢这种组合的方式. 写 ...
- 搜索:BFS
如果题目真的要考察宽度优先搜索,那么这类题目往往具有比较大的编码难度,换个说法,就是细枝末节特别多,状态特别复杂.. 剥茧抽丝,这里以一个比较“裸”的BFS作为例子,了解一下实现BFS的一些规范. 直 ...
- HDU 5876 Sparse Graph BFS+set删点
Problem Description In graph theory, the complement of a graph G is a graph H on the same vertices s ...
- [洛谷P2704] [NOI2001]炮兵阵地
洛谷题目链接:[NOI2001]炮兵阵地 题目描述 司令部的将军们打算在NM的网格地图上部署他们的炮兵部队.一个NM的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示), ...