基于创建型模式的“迷宫”构造

来源:互联网 发布:mac os server工具 编辑:程序博客网 时间:2024/05/21 10:36

本文在GOF《设计模式》一书“创建型模式”一章的例子和模式的基础上,将各个创建型模式有机的结合在一起。实现了“迷宫”构造过程的封装,增强了构造不同迷宫的可扩展性。

 

创建型模式:

抽象工厂

工厂方法

生成器

原型

单件

 

其中,抽象工厂是由工厂方法组成的,是一组相互关联的工厂方法的集合。

 

“迷宫”构造类图:

 

 

 

 

 

从类图中可以看出各个模式直接的关系,同时为了显示构造好的迷宫图案,还使用了“策略模式”用于画出迷宫(图中的MazeDrawer类层次)。

 

以下是各个模块的C++实现:

  1. #ifndef _PART_H_
  2. #define _PART_H_
  3. //Part.h
  4. enum Direction
  5. {   
  6.     East,
  7.     South,
  8.     West,
  9.     North   
  10. };
  11. class MapSite
  12. {
  13. public:
  14.     virtual void Enter() = 0;
  15.     virtual char* GetInfo() = 0;
  16. };
  17. class Room:public MapSite
  18. {
  19. public:
  20.     Room(int roomNo)
  21.     {
  22.         _roomNo = roomNo;
  23.         for(int i=0; i<4; ++i)
  24.             _sides[i] = 0;
  25.     }
  26.     
  27.     MapSite* GetSide(Direction d) const
  28.     {
  29.         return _sides[d];
  30.     }
  31.     void SetSide(Direction d, MapSite* ms)
  32.     {
  33.         if(_sides[d] != 0)
  34.             delete _sides[d];
  35.         _sides[d] = ms;
  36.     }
  37.     virtual void Enter()
  38.     {
  39.     
  40.     }
  41.     virtual char* GetInfo()
  42.     {
  43.         return "Room";
  44.     }
  45.     int RoomNo() const
  46.     {
  47.         return _roomNo;
  48.     }
  49. private:
  50.     MapSite* _sides[4];
  51.     int _roomNo;
  52. };
  53. class Wall:public MapSite
  54. {
  55. public:
  56.     Wall()
  57.     {
  58.     
  59.     }
  60.     virtual void Enter()
  61.     {
  62.     
  63.     }
  64.     virtual char* GetInfo()
  65.     {
  66.         return "Wall";
  67.     }
  68. };
  69. class Door:public MapSite
  70. {
  71. public:
  72.     Door(Room* r1 = 0, Room* r2 = 0)
  73.     {
  74.         _room1 = r1;
  75.         _room2 = r2;
  76.         _isOpen = false;
  77.     }
  78.     
  79.     Room* OtherSideFrom(Room* r)
  80.     {
  81.         if(r == _room1)
  82.             return _room2;
  83.         else if(r == _room2)
  84.             return _room1;
  85.         return 0;
  86.     }
  87.     virtual void Enter()
  88.     {
  89.     
  90.     }
  91.     virtual char* GetInfo()
  92.     {
  93.         return "Door";
  94.     }
  95. private:
  96.     Room* _room1;
  97.     Room* _room2;
  98.     bool _isOpen;
  99. };
  100. class Spell
  101. {
  102. public:
  103.     Spell()
  104.     {}
  105. };
  106. class EnchantedRoom: public Room
  107. {
  108. public:
  109.     EnchantedRoom(int roomNo, Spell* spell):Room(roomNo)
  110.     {
  111.         _spell = spell;
  112.     }
  113.     virtual void Enter()
  114.     {
  115.     
  116.     }
  117.     virtual char* GetInfo()
  118.     {
  119.         return "EnchantedRoom";
  120.     }
  121. private:
  122.     Spell* _spell;
  123. };
  124. class DoorNeedingSpell:public Door
  125. {
  126. public:
  127.     DoorNeedingSpell(Room* r1, Room* r2):Door(r1, r2)
  128.     {
  129.     
  130.     }
  131.     virtual void Enter()
  132.     {
  133.     
  134.     }
  135.     virtual char* GetInfo()
  136.     {
  137.         return "DoorNeedingSpell";
  138.     }
  139. };
  140. class RoomWithABomb: public Room
  141. {
  142. public:
  143.     RoomWithABomb(int roomNo):Room(roomNo)
  144.     {
  145.     
  146.     }
  147.     virtual void Enter()
  148.     {
  149.     
  150.     }
  151.     virtual char* GetInfo()
  152.     {
  153.         return "RoomWithABomb";
  154.     }
  155. };
  156. class BombedWall:public Wall
  157. {
  158. public:
  159.     BombedWall()
  160.     {
  161.     
  162.     }
  163.     virtual void Enter()
  164.     {
  165.     
  166.     }
  167.     virtual char* GetInfo()
  168.     {
  169.         return "BombedWall";
  170.     }
  171. };
  172. class Maze
  173. {
  174. public:
  175.     Maze(int xsize=1, int ysize=1)
  176.     {
  177.         if(xsize<=0 || ysize<=0)
  178.         {
  179.             xsize = ysize = 1;
  180.         }
  181.         _xsize = xsize;
  182.         _ysize = ysize;
  183.         _roomList = new Room*[_xsize*_ysize];
  184.         for(int i=0; i<_xsize*_ysize; ++i)
  185.             _roomList[i] = 0;
  186.         
  187.     }
  188.     void AddRoom(Room* r)
  189.     {
  190.         int rno = r->RoomNo();
  191.         
  192.         _roomList[rno] = r;
  193.     }
  194.     Room* RoomNo(int rno) const
  195.     {
  196.         for(int i=0; i<_xsize*_ysize; ++i)
  197.         {
  198.             if(_roomList[rno] == 0)
  199.                 continue;
  200.             if(_roomList[rno]->RoomNo() == rno)
  201.                 return _roomList[rno];
  202.         }
  203.         return 0;
  204.     }
  205.     
  206.     int XSize() const
  207.     {
  208.         return _xsize;
  209.     }
  210.     int YSzie() const
  211.     {
  212.         return _ysize;
  213.     }
  214.     int Size() const
  215.     {
  216.         return _xsize*_ysize;
  217.     }
  218.     ~Maze()
  219.     {
  220.     
  221.     }
  222. private:
  223.     Room** _roomList;
  224.     int _xsize;
  225.     int _ysize;
  226. };
  227. #endif

/////////////////////////////////////////////////////////////////////////////////////////////////////////

  1. //PartFactory.h
  2. #ifndef _PART_FACTORY_H_
  3. #define _PART_FACTORY_H_
  4. #include "Part.h"
  5. #include <string>
  6. class BombedPartFactory;
  7. class EnchantedPartFactory;
  8. class PartFactory
  9. {
  10. public:
  11.     static PartFactory* Instance();
  12.     
  13.     static void SetMazeStyle(std::string style)
  14.     {
  15.         _mazeStyle = style;
  16.     }
  17. private:
  18.     static std::string _mazeStyle;
  19.     static PartFactory* _instance;
  20. protected:
  21.     PartFactory(){}
  22. public:
  23.     virtual Room* MakeRoom(int rno) const
  24.     {
  25.         return new Room(rno);
  26.     }
  27.     
  28.     virtual Wall* MakeWall() const
  29.     {
  30.         return new Wall();
  31.     }
  32.     virtual Door* MakeDoor(Room* r1, Room* r2) const
  33.     {
  34.         return new Door(r1, r2);
  35.     }
  36. };
  37. class EnchantedPartFactory:public PartFactory
  38. {
  39. public:
  40.     EnchantedPartFactory(){}
  41.     virtual Room* MakeRoom(int rno) const
  42.     {
  43.         return new EnchantedRoom(rno, CastSpell());
  44.     }   
  45.     virtual Door* MakeDoor(Room* r1, Room* r2) const
  46.     {
  47.         return new DoorNeedingSpell(r1, r2);
  48.     }
  49. protected:
  50.     Spell* CastSpell() const
  51.     {
  52.         return 0;
  53.     }
  54. };
  55. class BombedPartFactory:public PartFactory
  56. {
  57. public:
  58.     BombedPartFactory(){}
  59.     virtual Room* MakeRoom(int rno) const
  60.     {
  61.         return new RoomWithABomb(rno);
  62.     }
  63.     
  64.     virtual Wall* MakeWall() const
  65.     {
  66.         return new BombedWall();
  67.     }
  68. };
  69. #endif

 

//////////////////////////////////////////////////////////////////////////

  1. //PartFactory.cpp
  2. #include "PartFactory.h"
  3. PartFactory* PartFactory::_instance = 0;
  4. std::string PartFactory::_mazeStyle;
  5. PartFactory* PartFactory::Instance()
  6. {
  7.     if(_instance == 0)
  8.     {
  9.         if(_mazeStyle == "bombed")
  10.             _instance = new BombedPartFactory();
  11.         else if(_mazeStyle == "enchanted")
  12.             _instance = new EnchantedPartFactory();
  13.         else
  14.             _instance = new PartFactory();
  15.     }
  16.     return _instance;
  17. }

 

////////////////////////////////////////////////////////////////////

  1. //MazeBuilder.h
  2. #ifndef _MAZE_BUILDER_H_
  3. #define _MAZE_BUILDER_H_
  4. #include "PartFactory.h"
  5. class MazeBuilder
  6. {
  7. public:
  8.     MazeBuilder()
  9.     {
  10.         BuildMaze();
  11.     }
  12.     void BuildMaze()
  13.     {
  14.         _maze = new Maze(8, 8);
  15.         _factory = PartFactory::Instance();
  16.     }
  17.     Maze* GetMaze()
  18.     {
  19.         return _maze;
  20.     }
  21.     virtual void BuildRoom(int rno) 
  22.     {
  23.         //emtpy
  24.     }
  25.     virtual void BuildDoor(int roomFrom, int roomTo)
  26.     {
  27.         //emtpy
  28.     }
  29.     
  30. protected:
  31.     Direction CommonWall(Room* r1, Room* r2)
  32.     {
  33.         int xs = _maze->XSize();
  34.         Direction dir;
  35.         if(r1->RoomNo()+1 == r2->RoomNo())
  36.             dir = East;
  37.         if(r1->RoomNo()-1 == r2->RoomNo())
  38.             dir = West;
  39.         if(r1->RoomNo()-xs == r2->RoomNo())
  40.             dir = North;
  41.         if(r1->RoomNo()+xs == r2->RoomNo())
  42.             dir = South;
  43.         return dir;
  44.     }
  45.     
  46.     Maze* _maze;
  47.     PartFactory* _factory;
  48.     
  49. };
  50. class StdMazeBuilder:public MazeBuilder
  51. {
  52. public:
  53.     StdMazeBuilder(){}
  54.     virtual void BuildRoom(int rno) 
  55.     {
  56.         if(!_maze->RoomNo(rno))
  57.         {
  58.             Room* r = _factory->MakeRoom(rno);
  59.             _maze->AddRoom(r);
  60.             r->SetSide(North, _factory->MakeWall());
  61.             r->SetSide(South, _factory->MakeWall());
  62.             r->SetSide(East, _factory->MakeWall());
  63.             r->SetSide(West, _factory->MakeWall());
  64.         }
  65.     }
  66.     virtual void BuildDoor(int roomFrom, int roomTo)
  67.     {
  68.         Room* r1 = _maze->RoomNo(roomFrom);
  69.         Room* r2 = _maze->RoomNo(roomTo);
  70.         Door* d = _factory->MakeDoor(r1, r2);
  71.         r1->SetSide(CommonWall(r1,r2), d);
  72.         r2->SetSide(CommonWall(r2,r1), d);
  73.     }
  74.     
  75. };
  76. #endif

 

////////////////////////////////////////////////////////////

  1. //MazeDrawer.h
  2. #ifndef _MAZE_DRAW_H_
  3. #define _MAZE_DRAW_H_
  4. #include "Part.h"
  5. #include <iostream>
  6. class MazeDrawer
  7. {
  8. public:
  9.     virtual void DrawMaze(Maze* maze)
  10.     {
  11.         for(int i=0; i<maze->Size(); ++i)
  12.         {
  13.             Room* r = maze->RoomNo(i);
  14.             if(r != 0)
  15.             {
  16.                 std::cout << r->GetInfo() << " " << r->RoomNo() << "#:" << std::endl;
  17.                 std::string dir;
  18.                 for(int j=0; j<4; ++j)
  19.                 {
  20.                     switch(j)
  21.                     {
  22.                     case East:
  23.                             dir = "East";
  24.                         break;
  25.                     case South:
  26.                             dir = "South";
  27.                         break;
  28.                     case West:
  29.                             dir = "West";
  30.                         break;
  31.                     case North:
  32.                             dir = "North";
  33.                         break;
  34.                     }
  35.                     std::cout << "    " << dir << ":" << r->GetSide((Direction)j)->GetInfo() << std::endl;
  36.                 }
  37.             }
  38.         }
  39.     }
  40. };
  41. #endif

 

//////////////////////////////////////////////////////////////////

  1. //MazeGame.h
  2. #ifndef _MAZE_GAME_H_
  3. #define _MAZE_GAME_H_
  4. #include "MazeBuilder.h"
  5. #include "MazeDrawer.h"
  6. class MazeGame
  7. {
  8. public:
  9.     MazeGame(MazeDrawer* md=0)
  10.     {
  11.         _mazeDrawer = md;
  12.     }
  13.     virtual Maze* CreateMaze(MazeBuilder& mb) = 0;
  14.     void DeleteMaze(Maze* maze)
  15.     {}
  16.     
  17.     void DrawMaze(Maze* maze)
  18.     {
  19.         if(_mazeDrawer != 0)
  20.             _mazeDrawer->DrawMaze(maze);
  21.     }
  22. private:
  23.     MazeDrawer* _mazeDrawer;
  24. };
  25. class Game1:public MazeGame
  26. {
  27. public:
  28.     Game1(MazeDrawer* md):MazeGame(md){}
  29.     virtual Maze* CreateMaze(MazeBuilder& mb)
  30.     {
  31.         for(int i=0; i<24; ++i)
  32.             mb.BuildRoom(i);
  33.         
  34.         mb.BuildDoor(0,1);
  35.         mb.BuildDoor(1,2);
  36.         mb.BuildDoor(2,10);
  37.         mb.BuildDoor(10,11);
  38.         mb.BuildDoor(11,12);
  39.         mb.BuildDoor(12,20);
  40.         mb.BuildDoor(20,21);
  41.         mb.BuildDoor(21,22);
  42.         mb.BuildDoor(22,14);
  43.         mb.BuildDoor(14,15);
  44.         return mb.GetMaze();
  45.     }
  46. };
  47. #endif

 

/////////////////////////////////////////////////////////////////

  1. // MazeGame.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "MazeGame.h"
  5. int _tmain(int argc, _TCHAR* argv[])
  6. {
  7.     PartFactory::SetMazeStyle("enchanted");
  8.     MazeGame* game = new Game1(new MazeDrawer());
  9.     Maze* maze = game->CreateMaze(StdMazeBuilder());
  10.     game->DrawMaze(maze);
  11.     return 0;
  12. }

 

参考文献:GOF《设计模式》

希望通道中人提出意见建议,共同改善完善,共同交流:hm.y@live.cn