将一个复杂的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
适用性:
1当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时
2 当构造过程必须允许被构造的对象有不同的表示时
效果:
1使你可以改变一个产品的内部表示,Builder提供给导向器一个构造产品的抽象接口,该接口可以隐藏这个产品的表示和内部结构。
2它将构造代码与表示代码分开,Builder模式通过封装一个复杂的对象的创建和表示发表过法提高了对象的模块性。每个ConcreteBuilder包含了创建和装配一个产品的所有代码,不同的Director可以复用相同部件集合的基础上构建不同的Product
3对构造过程进行精细控制,是在导向者的控制下一步一步构造产品的,当该产品完成时才从生成器取回。Builder接口更好的反映了产品的构造过程
实现:
1装配和构造接口 Builder接口必须足够普遍以便为各种类型的具体生成器构造产品
2产品没有抽象类
3Builder中缺省方法为空,不生明为纯虚成员函数,而是把它们定义为空方法,允许客户只定义他们所感兴趣的操作。
Abstract Factory与Builder比较
共同点 1创建复杂对象
不同点 1 Builder用于一步步构造一个复杂对象,并最终返回产品
2 Abstract Factory用于多个系列产品的对象,立即返回产品
代码如下:
Builder.h
- #include <string>
- #define MAX_ROOM_NO 30
- enum Direction {North,South,East,West,Length};
- class Mapsite
- {
- public:
- Mapsite(){}
- virtual ~Mapsite(){}
- virtual void Enter() = 0;
- };
- class Room : public Mapsite
- {
- public:
- Room(int roomNo);
- int GetRoomNo(){return roomNumber;}
- Mapsite* GetSide(Direction) const;
- void SetSide(Direction,Mapsite*);
- virtual void Enter();
- private:
- Mapsite* _sides[4];
- int roomNumber;
- };
- class Wall:public Mapsite
- {
- public:
- Wall();
- virtual void Enter();
- };
- class Door:public Mapsite
- {
- public:
- Door(Room* = 0,Room* = 0);
- virtual void Enter();
- Room * OtherSideFrom(Room*);
- private:
- Room* _room1;
- Room* _room2;
- bool _isOpen;
- };
- class Maze {
- public:
- //Maze();
- void AddRoom(Room *);
- Room* RoomNo(int) const;
- private:
- Room *a[MAX_ROOM_NO];
- };
- class MazeBuilder
- {
- public:
- virtual void BuildMaze(){}
- virtual void BuildRoom(int room){}
- virtual void BuildDoor(int roomFrom,int roomTo){}
- virtual Maze* GetMaze(){return 0;}
- protected:
- //MazeBuilder();
- };
- class MazeGame
- {
- public:
- Maze* CreateMaze(MazeBuilder& builder);
- };
- class StandardMazeBuilder:public MazeBuilder
- {
- public:
- StandardMazeBuilder();
- virtual void BuildMaze();
- virtual void BuildRoom(int room);
- virtual void BuildDoor(int roomFrom,int roomTo);
- virtual Maze* GetMaze();
- private:
- //Direction CommonWall(Room*,Room*);
- Maze* _currentMaze;
- };
Builder.cpp
- #include <iostream>
- using namespace std;
- #include "Builder.h"
- string Direstr[Length] ={
- "North",
- "South",
- "East",
- "West"
- };
- Room::Room(int roomNo)
- {
- cout<<"Make "<<roomNo<<" room"<<endl;
- roomNumber = roomNo;
- }
- void Room::SetSide(Direction dire,Mapsite* map)
- {
- cout<<"Build a Wall on Direction "<<Direstr[dire]<<endl;
- }
- void Room::Enter()
- {
- cout<<"Room enter"<<endl;
- }
- Wall::Wall()
- {
- cout<<"Make a wall"<<endl;
- }
- void Wall::Enter()
- {
- cout<<"Wall enter"<<endl;
- }
- void Door::Enter()
- {
- cout<<"Door enter"<<endl;
- }
- void Maze::AddRoom(Room *r)
- {
- cout<<"Add room to the maze!"<<endl;
- a[r->GetRoomNo()]=r;
- }
- Room* Maze::RoomNo(int roomNO) const
- {
- for (int i=0;i<MAX_ROOM_NO;i++)
- { if (i == roomNO)
- if (!a[i])
- return a[i];
- else
- return 0;
- }
- return 0;
- }
- Door::Door(Room* r1,Room* r2)
- {
- cout<<"A door is installed between 2 rooms"<<endl;
- }
- Maze* MazeGame::CreateMaze(MazeBuilder& builder)
- {
- builder.BuildMaze();
- builder.BuildRoom(1);
- builder.BuildRoom(2);
- builder.BuildDoor(1,2);
- return builder.GetMaze();
- }
- void StandardMazeBuilder::BuildMaze()
- {
- _currentMaze=new Maze;
- }
- Maze* StandardMazeBuilder::GetMaze()
- {
- return _currentMaze;
- }
- void StandardMazeBuilder::BuildRoom(int n)
- {
- if (!_currentMaze->RoomNo(n))
- {
- Room *room = new Room(n);
- _currentMaze->AddRoom(room);
- room->SetSide(North,new Wall);
- room->SetSide(South,new Wall);
- room->SetSide(East,new Wall);
- room->SetSide(West,new Wall);
- }
- }
- void StandardMazeBuilder::BuildDoor(int n1,int n2)
- {
- Room *r1=_currentMaze->RoomNo(n1);
- Room *r2=_currentMaze->RoomNo(n2);
- Door *d = new Door(r1,r2);
- r1->SetSide(West,d);
- r2->SetSide(North,d);
- }
- StandardMazeBuilder::StandardMazeBuilder()
- {
- _currentMaze = 0;
- }
main.cpp
- #include "Builder.h"
- #include <iostream>
- using namespace std;
- int main()
- {
- Maze* maze;
- cout<<"1"<<endl;
- MazeGame game;
- StandardMazeBuilder builder;
- game.CreateMaze(builder);
- maze = builder.GetMaze();
- return 0;
- }