设计模式之生成器(Builder)----对象创建型模式
1.意图
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
2.适用性
1)当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2)当构造过程必须允许被构造的对象有不同的表示时。
3.结构( 如图B1 )
4.参与者
*Builder
--为创建一个Product对象的各个部件指定抽象接口。
*ConcreteBuilder
---实现Builder的接口以构造和装配该产品的各个部件。
---定义并明确他所创建的表示。
---提供一个检索产品的接口。(协作中四:客户从生成器中检索产品。)
*Director
---构造一个使用Builder接口的对象。
*Product
---表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。
---包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
5.协作
1)客户创建Director对象,并用它所想要的Builder对象进行配置 。
2)一旦产品部件被生成,导向器就会通知生成器。
3)生成器处理导向器的请求,并将部件添加到该产品中。
4)客户从生成器中检索产品。
下面交互图说明Builder和Director是如何与一个客户协作的。(图B2)
6.代码示例:
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();
};
Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
builder.BuildMaze();
builder.BuildRoom(1);
builder.BuildRoom(2);
builder.BuildDoor(1, 2);
return builder.GetMaze();
}
Maze* MazeGame::CreateComplexMaze (MazeBuilder& builder) {
builder.BuildRoom(1);
// ...
builder.BuildRoom(1001);
return builder.GetMaze();
}
class StandardMazeBuilder : public MazeBuilder {
public:
StandardMazeBuilder();
virtual void BuildMaze();
virtual void BuildRoom(int);
virtual void BuildDoor(int, int);
virtual Maze* GetMaze();
private:
Direction CommonWall(Room*, Room*);
Maze* _currentMaze;
};
StandardMazeBuilder::StandardMazeBuilder () {
_currentMaze = 0;
}
void StandardMazeBuilder::BuildMaze () {
_currentMaze = new Maze;
}
Maze *StandardMazeBuilder::GetMaze () {
Maze* maze = _currentMaze;
return maze;
}
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(CommonWall(r1,r2), d);
r2->SetSide(CommonWall(r2,r1), d);
}
void dummy() {
Maze* maze;
MazeGame game;
StandardMazeBuilder builder;
game.CreateMaze(builder);
maze = builder.GetMaze();
}
class CountingMazeBuilder : public MazeBuilder {
public:
CountingMazeBuilder();
virtual void BuildMaze();
virtual void BuildRoom(int);
virtual void BuildDoor(int, int);
virtual void AddWall(int, Direction);
void GetCounts(int&, int&) const;
private:
int _doors;
int _rooms;
};
/*
*/
CountingMazeBuilder::CountingMazeBuilder () {
_rooms = _doors = 0;
}
void CountingMazeBuilder::BuildRoom (int) {
_rooms++;
}
void CountingMazeBuilder::BuildDoor (int, int) {
_doors++;
}
void CountingMazeBuilder::GetCounts (
int& rooms, int& doors
) const {
rooms = _rooms;
doors = _doors;
}
void dummy1() {
int rooms, doors;
MazeGame game;
CountingMazeBuilder builder;
game.CreateMaze(builder);
builder.GetCounts(rooms, doors);
cout << "The maze has "
<< rooms << " rooms and "
<< doors << " doors" << endl;
}