<script src="http://wz.csdn.net/javascripts/vote.js" type="text/javascript"></script> style="MARGIN-TOP: 0px; FLOAT: left" border="0" marginwidth="0" framespacing="0" marginheight="0" src="http://wz.csdn.net/vote.aspx?t=%u5E38%u89C1%u8BBE%u8BA1%u6A21%u5F0F%u7684%u89E3%u6790%u548C%u5B9E%u73B0%28C++%29%u4E4B%u4E09-Builder%u6A21%u5F0F%20-%20whf%u7684%u4E13%u680F%20-%20CSDNBlog&u=http%3A//blog.csdn.net/whf727/archive/2007/06/25/1665394.aspx" frameborder="0" noresize="noresize" width="54" scrolling="no" height="75">
常见设计模式的解析和实现(C++)之三-Builder模式 <script src="http://blog.csdn.net/count.aspx?ID=1665394&Type=Rank" type="text/javascript"></script>
作用:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
UML结构图:
![](http://www.yesky.com/20020723/fangz20723_2.gif)
适用于以下情况:
1)当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2)当构造过程必须允许被构造的对象有不同的表示时。
抽象基类:
1)Builder:这个基类是全部创建对象过程的抽象,提供构建不同组成部分的接口函数
接口:
1)Builder::BuildPartA,Builder::BuildPartB:是对一个对象不同部分的构建函数接口,Builder的派生类来具体实现.
另 外还有一个需要注意的函数,就是Director::Construct函数,这个函数里面通过调用上面的两个接口函数完成对象的构建--也就是说各个不 同部分装配的过程都是一致的(同样的调用的Construct函数),但是不同的构建方式会有不同的表示(根据Builder的实际类型来决定如何构建, 也就是多态)
解析:
Builder模式是基于这样的一个情况:一个对象可能有不同的组成部分,这几个部分的不同的创建对象会有不 同的表示,但是各个部分之间装配的方式是一致的.比方说一辆单车,都是由车轮车座等等的构成的(一个对象不同的组成部分),不同的品牌生产出来的也不一样 (不同的构建方式).虽然不同的品牌构建出来的单车不同,但是构建的过程还是一样的(哦,你见过车轮长在车座上的么?).
也就是说,Director::Construct函数中固定了各个组成部分的装配方式,而具体是装配怎样的组成部分由Builder的派生类实现.
实现:
Builder 模式的实现基于以下几个面向对象的设计原则:1)把变化的部分提取出来形成一个基类和对应的接口函数,在这里不会变化的是都会创建PartA和 PartB,变化的则是不同的创建方法,于是就抽取出这里的Builder基类和BuildPartA,BuildPartB接口函数 2)采用聚合的方式聚合了会发生变化的基类,就是这里Director聚合了Builder类的指针.
1)Builder.h
/**/
/* *******************************************************************
created: 2006/07/19
filename: Builder.h
author: 李创
http://www.cppblog.com/converse/
purpose: Builder模式的演示代码
******************************************************************** */
#ifndef BUILDER_H
#define
BUILDER_H
//
虚拟基类,是所有Builder的基类,提供不同部分的构建接口函数
class
Builder
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
public :
![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
Builder()
{} ;
![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
virtual ~ Builder()
{}
// 纯虚函数,提供构建不同部分的构建接口函数
virtual void BuilderPartA() = 0 ;
virtual void BuilderPartB() = 0 ;
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
//
使用Builder构建产品,构建产品的过程都一致,但是不同的builder有不同的实现
//
这个不同的实现通过不同的Builder派生类来实现,存有一个Builder的指针,通过这个来实现多态调用
class
Director
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
public :
Director(Builder * pBuilder);
~ Director();
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
void Construct();
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
private :
Builder * m_pBuilder;
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
//
Builder的派生类,实现BuilderPartA和BuilderPartB接口函数
class
ConcreateBuilder1
:
public
Builder
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
public :
![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
ConcreateBuilder1()
{}
virtual ~ ConcreateBuilder1()
{}
virtual void BuilderPartA();
virtual void BuilderPartB();
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
//
Builder的派生类,实现BuilderPartA和BuilderPartB接口函数
class
ConcreateBuilder2
:
public
Builder
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
public :
![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
ConcreateBuilder2()
{}
virtual ~ ConcreateBuilder2()
{}
virtual void BuilderPartA();
virtual void BuilderPartB();
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
#endif
2)Builder.cpp
/**/
/* *******************************************************************
created: 2006/07/19
filename: Builder.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Builder模式的演示代码
******************************************************************** */
#include
"
Builder.h
"
#include
<
iostream
>
void
ConcreateBuilder1::BuilderPartA()
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
std::cout << " BuilderPartA by ConcreateBuilder1/n " ;
}
void
ConcreateBuilder1::BuilderPartB()
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
std::cout << " BuilderPartB by ConcreateBuilder1/n " ;
}
void
ConcreateBuilder2::BuilderPartA()
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
std::cout << " BuilderPartA by ConcreateBuilder2/n " ;
}
void
ConcreateBuilder2::BuilderPartB()
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
std::cout << " BuilderPartB by ConcreateBuilder2/n " ;
}
Director::Director(Builder
*
pBuilder)
: m_pBuilder(pBuilder)
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
}
Director::
~
Director()
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
delete m_pBuilder;
m_pBuilder = NULL;
}
//
Construct函数表示一个对象的整个构建过程,不同的部分之间的装配方式都是一致的,
//
首先构建PartA其次是PartB,只是根据不同的构建者会有不同的表示
void
Director::Construct()
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
m_pBuilder -> BuilderPartA();
m_pBuilder -> BuilderPartB();
}
3)Main.cpp
/**/
/* *******************************************************************
created: 2006/07/20
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Builder模式的测试代码
******************************************************************** */
#include
"
Builder.h
"
#include
<
stdlib.h
>
int
main()
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
Builder * pBuilder1 = new ConcreateBuilder1;
Director * pDirector1 = new Director(pBuilder1);
pDirector1 -> Construct();
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
Builder * pBuilder2 = new ConcreateBuilder2;
Director * pDirector2 = new Director(pBuilder2);
pDirector2 -> Construct();
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
delete pDirector1;
delete pDirector2;
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
system( " pause " );
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
return 0 ;
}
用处:Builder模式要解决的也正是这样的问题:当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),我们要要复杂对象的创建过程和这个对象的表示(展示)分离开来,这样做的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。
代码实现:University.h、University.cpp、Registe.h、Registe.cpp、Student.h、Student.cpp、MainBuilder.cpp