Читайте также:
|
|
BuildMaze инстанцирует объект класса Maze, который будет собираться другими операциями и, в конце концов, возвратится клиенту (с помощью GetMaze):
void StandardMazeBuilder:: BuildMaze () {
_currentMaze = new Maze; j
Maze* StandardMazeBuilder::GetMaze () {
return _currentMaze; }
Операция BuildRoom создает комнату и строит вокруг нее стены:
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);
Чтобы построить дверь между двумя комнатами, StandardMazeBuilder находит обе комнаты в лабиринте и их общую стену:
void StandardMazeBuilder: rBuildDoor (int nl, int n2) { Room* rl = _currentMaze->RoomNo (nl); Room* r2 = _currentMaze->RoomNo (n2); Door* d = new Door(rl, r2);
rl->SetSide(CommonWall(rl,r2), d); r2->SetSide(CommonWall(r2,rl), d); }
Теперь для создания лабиринта клиенты могут использовать Great eMaze в сочетании с StandardMazeBuilder:
Maze* maze; MazeGame game; StandardMazeBuilder builder;
game. CreateMaze (builder); maze = builder. GetMaze ();
Мы могли бы поместить все операции класса StandardMazeBuilder в класс Maze и позволить каждому лабиринту строить самого себя. Но чем меньше класс Maze, тем проще он для понимания и модификации, a StandardMazeBuilder легко отделяется от Maze. Еще важнее то, что разделение этих двух классов позволяет иметь множество разновидностей класса MazeBuilder, в каждом из которых есть собственные классы для комнат, дверей и стен.
Необычным вариантом MazeBuiIder является класс Count ingMazeBuiIder. Этот строитель вообще не создает никакого лабиринта, он лишь подсчитывает число компонентов разного вида, которые могли бы быть созданы:
class CountingMazeBuilder: public MazeBuilder { public:
CountingMazeBuilderO;
virtual void BuildMazeO;
virtual void BuildRoom(int);
virtual void BuildDoor (int, int);
virtual void AddWall(int, Direction);
void GetCounts (int&, int&) const; private:
int _doors,-int _rooms;
Конструктор инициализирует счетчики, а замещенные операции класса MazeBuilder увеличивают их:
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; i
Вот как клиент мог бы использовать класс CountingMazeBuilder:
int rooms, doors; MazeGame game; CountingMazeBuilder builder;
game.CreateMaze(builder); buiIder.GetCount s(rooms, doors);
cout «"В лабиринте есть "
Паттерн Factory Method
«rooms «" комнат и "
«doors «" дверей" «endl;
Известные применения
Приложение для конвертирования из формата RTF взято из библиотеки ЕТ++ [WGM88]. В ней используется строитель для обработки текста, хранящегося в таком формате.
Паттерн строитель широко применяется в языке Smalltalk-80 [РагЭО]:
а класс Parser в подсистеме компиляции - это распорядитель, которому в качестве аргумента передается объект ProgramNodeBuilder. Объект класса Parser извещает объект ProgramNodeBuilder после распознава-ния каждой ситаксической конструкции. После завершения синтаксического разбора Parser обращается к строителю за созданным деревом разбора и возвращает его клиенту;
a Class Builder- это строитель, которым пользуются все классы для создания своих подклассов. В данном случае этот класс выступает одновременно в качестве распорядителя и продукта;
a ByteCodeStream- это строитель, который создает откомпилированный метод в виде массива байтов. ByteCodeStream является примером нестандартного применения паттерна строитель, поскольку сложный объект представляется как массив байтов, а не как обычный объект Smalltalk. Но интерфейс к ByteCodeStream типичен для строителя, и этот класс легко можно было бы заменить другим, который представляет программу в виде составного объекта.
Дата добавления: 2015-09-11; просмотров: 75 | Поможем написать вашу работу | Нарушение авторских прав |