// MazeBuilder.h
#ifndef _MAZE_BUILDER_H
#define _MAZE_BUILDER_H
#include "Maze.h"
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() {}
};
#endif
注意CreateMaze的实现:
class MazeGame_Builder {
public:
Maze* CreateMaze(MazeBuilder& builder) {
builder.BuildMaze();
builder.BuildRoom(1);
builder.BuildRoom(2);
builder.BuildDoor(1, 2);
return builder.GetMaze();
}
Maze* CreateComplexMaze(MazeBuilder& builder) {
for (int i = 0; i < 5; ++i)
builder.BuildRoom(i);
return builder.GetMaze();
}
};
比较利用Builder模式和利用Abstract Factory模式我们编写函数CreateMaze的不同。当我们利用Abstract Factory模式时,CreateMaze函数需要写清楚创建Maze的整个过程,就和没有使用Design Pattern时是一样的(我们需要创建新的对象并且需要指明这些对象之间的关系),不同之处在于我们创建对象时,不是用new操作符以及实际的类名,而是通过MazeFactory类所提供的接口。但是当我们使用Builder模式时,创建Maze的方式大大改变,应该说是变得更简单了。在CreateMaze函数里,我们只需要指明我们需要创建什么,而不需要去考虑所创建的这些事物之间的相互关系。至于这些对象之间的关系有Builder来实现。
下面是一个Builder的实现:
// StandardMazeBuilder.h
#ifndef _STANDARD_MAZE_BUILDER_H
#define _STANDARD_MAZE_BUILDER_H
#include "Maze.h"
#include "Room.h"
#include "MazeBuilder.h"
//#include "Direction.h"
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;
};
#endif
// StandardMazeBuilder.cpp
#include "StandardMazeBuilder.h"
#include "Door.h"
#include "Wall.h"
StandardMazeBuilder::StandardMazeBuilder() {
_currentMaze = 0;
}
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(CommonWall(r1, r2), d);
r2->SetSide(CommonWall(r2, r1), d);
}
Direction StandardMazeBuilder::CommonWall(Room* r1, Room* r2) {
return South;
}
利用Builder模式我们还可以实现一些其他的功能,比如我们可以在Buider中记录创建的各种对象的个数。
例如:
// CountingMazeBuilder.h
#ifndef _COUNT_MAZE_BUILDER_H
#define _COUNT_MAZE_BUILDER_H
#include "MazeBuilder.h"
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;
};
#endif
// CountingMazeBuilder.cpp
#include "CountingMazeBuilder.h"
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;
}
这个类完全没有创建任何对象,他只是记录了一下每一种对象所创建的次数而已。
根据上面的实现来看,Builder模式在创建对象方面比Abstract Factory更加灵活。并且,使用Builder模式,用户在创建复杂对象时会更简单,因为整个创建复杂对象的逻辑都是在Builder中实现的。
有一点需要注意的是,在Builder类中,除了提供创建各种对象的方法之外,还必须提供一个方法用于获得所创建的对象。比如StandardMazeBuilder类中的GetMaze函数,以及CountingMazeBuilder函数中的GetCounts函数。这些函数在Abstract Factory模式中是不需要的。
阅读(721) | 评论(0) | 转发(0) |