設計模式之生成器(Builder)----對象創建型模式

                   設計模式之生成器(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;

}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章