标题: [设计模式讨论之]builder模式(生成器模式)]
无双
荣誉斑竹
Rank: 14Rank: 14Rank: 14Rank: 14
天才猪



UID 4
精华 84
积分 5863
帖子 11390
活跃指数 0
LU金币 4248 个
LU金条 0 个
阅读权限 200
注册 2003-9-16
来自 杭州
 
发表于 2003-11-27 20:09  资料  个人空间  主页 短消息  加为好友 
意图
将一个复杂对象的创建过程与它的表示分离 使同样的创建过程可以创建不同的表示

解释 也就是创建过程定义好接口 如下 下面这个创建接口是定义死的 但是 MazeBuilder 的不同子类可以根据自己的需要实现某个函数的功能,如BuildRoom可能根据子类需要而生成一个特殊的房间 这样更换迷宫的房间时 只要修改从MazeBuilder继承出来的子类的实现就可以 而不必修改客户类的实现
如下就是 修改实现时只要修改MazeBuilder 继承来的子类就可以 而不必修改MazeGame的实现

如下
Maze *MazeGame::CreateMaze(MazeBuilder &builder){
//下面是三步创建过程,builder可以根据自己的需要实现某个或是多个函数 或是某个函数的特殊实现
builder.BuildMaze();
builder.BuildRoom(1);
builder.BuildDoor(1,2);
//最后一步返回创建的结果
return builder.GetMaze();
}

上面的创建过程是固定的 也就是MazeGame::CreateMaze接口是固定的
可是实现是可变的 也就是可以根据自己需要从MazeBuilder 派生出不同的子类
然后把它传入MazeGame::CreateMaze接口从而得到不同的实现





不要问我结果 我只研究过程与思路
无双客栈
顶部
无双
荣誉斑竹
Rank: 14Rank: 14Rank: 14Rank: 14
天才猪



UID 4
精华 84
积分 5863
帖子 11390
活跃指数 0
LU金币 4248 个
LU金条 0 个
阅读权限 200
注册 2003-9-16
来自 杭州
 
发表于 2003-11-27 20:40  资料  个人空间  主页 短消息  加为好友 
例子
CODE

Sample Code
//创建者基类 这个类提供创建复杂对象的接口 接口的实现在子类中实现
   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();
   };

//客户,MazeGame是使用这个对象的客户
   Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
       builder.BuildMaze();
   
       builder.BuildRoom(1);
       builder.BuildRoom(2);
       builder.BuildDoor(1, 2);
   
       return builder.GetMaze();
   }

The builder hides the internal representation of the Maze and how these parts are assembled to complete the final maze. (No walls?)
//创建者子类 对基类中方法进行实现 以便控制创建结果
   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 () {
       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);
   }


//例子
Maze* maze;
   MazeGame game;
   StandardMazeBuilder builder;
   //在这里进行创建 产生一个maze
   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;
   }
//使用例子
int rooms, doors;
   MazeGame game;
   CountingMazeBuilder builder;
   //创建并返回对象 和上面相比 不同点在于传进去的子类不同了 这里是传CountingMazeBuilder 类的对象 所以产生结果也不一样
   game.CreateMaze(builder);
   builder.GetCounts(rooms, doors);
   
   cout << "The maze has "
        << rooms << " rooms and "
        << doors << " doors" << endl;





不要问我结果 我只研究过程与思路
无双客栈
顶部
无双
荣誉斑竹
Rank: 14Rank: 14Rank: 14Rank: 14
天才猪



UID 4
精华 84
积分 5863
帖子 11390
活跃指数 0
LU金币 4248 个
LU金条 0 个
阅读权限 200
注册 2003-9-16
来自 杭州
 
发表于 2003-11-27 20:47  资料  个人空间  主页 短消息  加为好友 
UML表示

derector
使用者 使用builder提供的接口进行创建对象的类

builder
创建者 定义了基本的创建接口

product
被构造的对象

concretbuilder
一个具体的创建者



 附件: 您所在的用户组无法下载或查看附件




不要问我结果 我只研究过程与思路
无双客栈
顶部
无双
荣誉斑竹
Rank: 14Rank: 14Rank: 14Rank: 14
天才猪



UID 4
精华 84
积分 5863
帖子 11390
活跃指数 0
LU金币 4248 个
LU金条 0 个
阅读权限 200
注册 2003-9-16
来自 杭州
 
发表于 2003-11-27 20:56  资料  个人空间  主页 短消息  加为好友 
时序图



 附件: 您所在的用户组无法下载或查看附件




不要问我结果 我只研究过程与思路
无双客栈
顶部
 



当前时区 GMT+8, 现在时间是 2008-12-2 01:44
乐悠LoveUnix论坛-京ICP备05005823号

Thanks to Discuz!  © 2001-2007    Power by LoveUnix.net
Processed in 0.074536 second(s), 6 queries , Gzip enabled

清除 Cookies - 联系我们 - 乐悠LoveUnix - Archiver