意图:将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。
适用性:
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 当构建过程必须允许被构建的对象有不同的表示时。
效果:
- 使得可以改变一个产品的内部表示。
- 使得构造代码和表示代码分离。
- 使得可以对构建过程进行更精确的控制。
演示模型和实现代码:
代码以构建Room为实例,而Room由四个Site组成,Site可以是Wall、Window、Door、Grass、Wood。(其中wood和grass分别表示木制墙和玻璃墙). 这里Room可以有3 Wall 1 Door 或 2 wall 1 Door 1 Window等各种表示。构建在具体Builder中实现,而在Director中表示,体现了效果3.
在Builder头文件下,首先我们创建各种要用到的类:
#ifndef _BUILDER_
#define _BUILDER_
#include <string>
#include <iostream>
using namespace std;
const int MAXSITE = 4;
class Site
{
public:
Site(string str):_mName(str){}
string _mName;
};
class Wall:public Site
{
public:
Wall():Site("wall"){}
};
class Wood:public Site
{
public:
Wood():Site("wood"){}
};
class Grass:public Site
{
public:
Grass():Site("grass"){}
};
class Door:public Site
{
public:
Door():Site("door"){}
};
class Window:public Site
{
public:
Window():Site("window"){}
};
class Room
{
public:
Room(){
for(int i = 0; i < MAXSITE; i++)
_mSite[i] = NULL;
}
void Printf()
{
for(int i = 0; i < MAXSITE; i++)
{
if(_mSite[i] != NULL)
cout<<_mSite[i]->_mName<<endl;
}
}
Site* _mSite[MAXSITE];
};
接着我们创建AbsBuilder,这里提供给向导器一个构造产品的抽象接口。因为不知道具体哪个类被创建并用于组成目标类,所以达到了效果2.
class AbsBuilder{
public:
AbsBuilder(){}
virtual void BuilderWall(){}
virtual void BuilderDoor(){}
virtual void BuilderWindow(){}
virtual void BuilderGrass(){}
virtual void BuilderWood(){}
virtual Room* GetRoom() = 0;
};
然后是具体创建BuilderA/B...,体现了可以改变产品的内部表示(效果1.)
class BuilderA:public AbsBuilder{
public:
BuilderA():_mNum(0){_mpRoom = new Room; }
virtual void BuilderWall(){_mpRoom->_mSite[_mNum++] = new Wall;}
virtual void BuilderDoor(){_mpRoom->_mSite[_mNum++] = new Door;}
virtual void BuilderWindow()
{
_mpRoom->_mSite[_mNum++] = new Window;
_mpRoom->_mSite[_mNum++] = new Window;
}
virtual Room* GetRoom(){return _mpRoom; }
private:
Room* _mpRoom;
int _mNum;
};
class BuilderB:public AbsBuilder{
public:
BuilderB():_mNum(0){_mpRoom = new Room; }
virtual void BuilderWood(){_mpRoom->_mSite[_mNum++] = new Wood;}
virtual void BuilderDoor(){_mpRoom->_mSite[_mNum++] = new Door;}
virtual void BuilderWindow()
{
_mpRoom->_mSite[_mNum++] = new Grass;
_mpRoom->_mSite[_mNum++] = new Grass;
}
virtual Room* GetRoom(){return _mpRoom; }
private:
Room* _mpRoom;
int _mNum;
};
#endif
BuilderA/B
在Director头文件下,创建类Director. 因为这里一步步构造产品,体现了效果4.
class Director{
public:
Director(AbsBuilder* builder){_mBuilder = builder;}
void construct()
{
_mBuilder->BuilderDoor();
_mBuilder->BuilderWall();
_mBuilder->BuilderWindow();
_mBuilder->BuilderGrass();
_mBuilder->BuilderWood();
}
private:
AbsBuilder* _mBuilder;
};
main函数中:
#include <iostream>
using namespace std;
#include "Builder.h"
#include "Director.h"
int main()
{
BuilderA* pBuilderA = new BuilderA;
Director directro(pBuilderA);
directro.construct();
Room* roomA = pBuilderA->GetRoom();
roomA->Printf();
cout<<endl;
BuilderB* pBuilderB = new BuilderB;
Director directroB(pBuilderB);
directroB.construct();
Room* roomB = pBuilderB->GetRoom();
roomB->Printf();
cout<<endl;
return 0;
}