Chinaunix首页 | 论坛 | 博客
  • 博客访问: 85052
  • 博文数量: 34
  • 博客积分: 1640
  • 博客等级: 上尉
  • 技术积分: 395
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-17 14:37
文章分类
文章存档

2008年(34)

我的朋友
最近访客

分类:

2008-04-17 20:25:36

// 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) |
给主人留下些什么吧!~~