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

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

创建型模式:

抽象工厂

工厂方法

生成器

原型

单件

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

“迷宫”构造类图:

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

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

  1. #ifndef_PART_H_
  2. #define_PART_H_
  3. //Part.h
  4. enumDirection
  5. {
  6. East,
  7. South,
  8. West,
  9. North
  10. };
  11. classMapSite
  12. {
  13. public:
  14. virtualvoidEnter()=0;
  15. virtualchar*GetInfo()=0;
  16. };
  17. classRoom:publicMapSite
  18. {
  19. public:
  20. Room(introomNo)
  21. {
  22. _roomNo=roomNo;
  23. for(inti=0;i<4;++i)
  24. _sides[i]=0;
  25. }
  26. MapSite*GetSide(Directiond)const
  27. {
  28. return_sides[d];
  29. }
  30. voidSetSide(Directiond,MapSite*ms)
  31. {
  32. if(_sides[d]!=0)
  33. delete_sides[d];
  34. _sides[d]=ms;
  35. }
  36. virtualvoidEnter()
  37. {
  38. }
  39. virtualchar*GetInfo()
  40. {
  41. return"Room";
  42. }
  43. intRoomNo()const
  44. {
  45. return_roomNo;
  46. }
  47. private:
  48. MapSite*_sides[4];
  49. int_roomNo;
  50. };
  51. classWall:publicMapSite
  52. {
  53. public:
  54. Wall()
  55. {
  56. }
  57. virtualvoidEnter()
  58. {
  59. }
  60. virtualchar*GetInfo()
  61. {
  62. return"Wall";
  63. }
  64. };
  65. classDoor:publicMapSite
  66. {
  67. public:
  68. Door(Room*r1=0,Room*r2=0)
  69. {
  70. _room1=r1;
  71. _room2=r2;
  72. _isOpen=false;
  73. }
  74. Room*OtherSideFrom(Room*r)
  75. {
  76. if(r==_room1)
  77. return_room2;
  78. elseif(r==_room2)
  79. return_room1;
  80. return0;
  81. }
  82. virtualvoidEnter()
  83. {
  84. }
  85. virtualchar*GetInfo()
  86. {
  87. return"Door";
  88. }
  89. private:
  90. Room*_room1;
  91. Room*_room2;
  92. bool_isOpen;
  93. };
  94. classSpell
  95. {
  96. public:
  97. Spell()
  98. {}
  99. };
  100. classEnchantedRoom:publicRoom
  101. {
  102. public:
  103. EnchantedRoom(introomNo,Spell*spell):Room(roomNo)
  104. {
  105. _spell=spell;
  106. }
  107. virtualvoidEnter()
  108. {
  109. }
  110. virtualchar*GetInfo()
  111. {
  112. return"EnchantedRoom";
  113. }
  114. private:
  115. Spell*_spell;
  116. };
  117. classDoorNeedingSpell:publicDoor
  118. {
  119. public:
  120. DoorNeedingSpell(Room*r1,Room*r2):Door(r1,r2)
  121. {
  122. }
  123. virtualvoidEnter()
  124. {
  125. }
  126. virtualchar*GetInfo()
  127. {
  128. return"DoorNeedingSpell";
  129. }
  130. };
  131. classRoomWithABomb:publicRoom
  132. {
  133. public:
  134. RoomWithABomb(introomNo):Room(roomNo)
  135. {
  136. }
  137. virtualvoidEnter()
  138. {
  139. }
  140. virtualchar*GetInfo()
  141. {
  142. return"RoomWithABomb";
  143. }
  144. };
  145. classBombedWall:publicWall
  146. {
  147. public:
  148. BombedWall()
  149. {
  150. }
  151. virtualvoidEnter()
  152. {
  153. }
  154. virtualchar*GetInfo()
  155. {
  156. return"BombedWall";
  157. }
  158. };
  159. classMaze
  160. {
  161. public:
  162. Maze(intxsize=1,intysize=1)
  163. {
  164. if(xsize<=0||ysize<=0)
  165. {
  166. xsize=ysize=1;
  167. }
  168. _xsize=xsize;
  169. _ysize=ysize;
  170. _roomList=newRoom*[_xsize*_ysize];
  171. for(inti=0;i<_xsize*_ysize;++i)
  172. _roomList[i]=0;
  173. }
  174. voidAddRoom(Room*r)
  175. {
  176. intrno=r->RoomNo();
  177. _roomList[rno]=r;
  178. }
  179. Room*RoomNo(intrno)const
  180. {
  181. for(inti=0;i<_xsize*_ysize;++i)
  182. {
  183. if(_roomList[rno]==0)
  184. continue;
  185. if(_roomList[rno]->RoomNo()==rno)
  186. return_roomList[rno];
  187. }
  188. return0;
  189. }
  190. intXSize()const
  191. {
  192. return_xsize;
  193. }
  194. intYSzie()const
  195. {
  196. return_ysize;
  197. }
  198. intSize()const
  199. {
  200. return_xsize*_ysize;
  201. }
  202. ~Maze()
  203. {
  204. }
  205. private:
  206. Room**_roomList;
  207. int_xsize;
  208. int_ysize;
  209. };
  210. #endif

/

  1. //PartFactory.h
  2. #ifndef_PART_FACTORY_H_
  3. #define_PART_FACTORY_H_
  4. #include"Part.h"
  5. #include<string>
  6. classBombedPartFactory;
  7. classEnchantedPartFactory;
  8. classPartFactory
  9. {
  10. public:
  11. staticPartFactory*Instance();
  12. staticvoidSetMazeStyle(std::stringstyle)
  13. {
  14. _mazeStyle=style;
  15. }
  16. private:
  17. staticstd::string_mazeStyle;
  18. staticPartFactory*_instance;
  19. protected:
  20. PartFactory(){}
  21. public:
  22. virtualRoom*MakeRoom(intrno)const
  23. {
  24. returnnewRoom(rno);
  25. }
  26. virtualWall*MakeWall()const
  27. {
  28. returnnewWall();
  29. }
  30. virtualDoor*MakeDoor(Room*r1,Room*r2)const
  31. {
  32. returnnewDoor(r1,r2);
  33. }
  34. };
  35. classEnchantedPartFactory:publicPartFactory
  36. {
  37. public:
  38. EnchantedPartFactory(){}
  39. virtualRoom*MakeRoom(intrno)const
  40. {
  41. returnnewEnchantedRoom(rno,CastSpell());
  42. }
  43. virtualDoor*MakeDoor(Room*r1,Room*r2)const
  44. {
  45. returnnewDoorNeedingSpell(r1,r2);
  46. }
  47. protected:
  48. Spell*CastSpell()const
  49. {
  50. return0;
  51. }
  52. };
  53. classBombedPartFactory:publicPartFactory
  54. {
  55. public:
  56. BombedPartFactory(){}
  57. virtualRoom*MakeRoom(intrno)const
  58. {
  59. returnnewRoomWithABomb(rno);
  60. }
  61. virtualWall*MakeWall()const
  62. {
  63. returnnewBombedWall();
  64. }
  65. };
  66. #endif

//

  1. //PartFactory.cpp
  2. #include"PartFactory.h"
  3. PartFactory*PartFactory::_instance=0;
  4. std::stringPartFactory::_mazeStyle;
  5. PartFactory*PartFactory::Instance()
  6. {
  7. if(_instance==0)
  8. {
  9. if(_mazeStyle=="bombed")
  10. _instance=newBombedPartFactory();
  11. elseif(_mazeStyle=="enchanted")
  12. _instance=newEnchantedPartFactory();
  13. else
  14. _instance=newPartFactory();
  15. }
  16. return_instance;
  17. }

  1. //MazeBuilder.h
  2. #ifndef_MAZE_BUILDER_H_
  3. #define_MAZE_BUILDER_H_
  4. #include"PartFactory.h"
  5. classMazeBuilder
  6. {
  7. public:
  8. MazeBuilder()
  9. {
  10. BuildMaze();
  11. }
  12. voidBuildMaze()
  13. {
  14. _maze=newMaze(8,8);
  15. _factory=PartFactory::Instance();
  16. }
  17. Maze*GetMaze()
  18. {
  19. return_maze;
  20. }
  21. virtualvoidBuildRoom(intrno)
  22. {
  23. //emtpy
  24. }
  25. virtualvoidBuildDoor(introomFrom,introomTo)
  26. {
  27. //emtpy
  28. }
  29. protected:
  30. DirectionCommonWall(Room*r1,Room*r2)
  31. {
  32. intxs=_maze->XSize();
  33. Directiondir;
  34. if(r1->RoomNo()+1==r2->RoomNo())
  35. dir=East;
  36. if(r1->RoomNo()-1==r2->RoomNo())
  37. dir=West;
  38. if(r1->RoomNo()-xs==r2->RoomNo())
  39. dir=North;
  40. if(r1->RoomNo()+xs==r2->RoomNo())
  41. dir=South;
  42. returndir;
  43. }
  44. Maze*_maze;
  45. PartFactory*_factory;
  46. };
  47. classStdMazeBuilder:publicMazeBuilder
  48. {
  49. public:
  50. StdMazeBuilder(){}
  51. virtualvoidBuildRoom(intrno)
  52. {
  53. if(!_maze->RoomNo(rno))
  54. {
  55. Room*r=_factory->MakeRoom(rno);
  56. _maze->AddRoom(r);
  57. r->SetSide(North,_factory->MakeWall());
  58. r->SetSide(South,_factory->MakeWall());
  59. r->SetSide(East,_factory->MakeWall());
  60. r->SetSide(West,_factory->MakeWall());
  61. }
  62. }
  63. virtualvoidBuildDoor(introomFrom,introomTo)
  64. {
  65. Room*r1=_maze->RoomNo(roomFrom);
  66. Room*r2=_maze->RoomNo(roomTo);
  67. Door*d=_factory->MakeDoor(r1,r2);
  68. r1->SetSide(CommonWall(r1,r2),d);
  69. r2->SetSide(CommonWall(r2,r1),d);
  70. }
  71. };
  72. #endif

  1. //MazeDrawer.h
  2. #ifndef_MAZE_DRAW_H_
  3. #define_MAZE_DRAW_H_
  4. #include"Part.h"
  5. #include<iostream>
  6. classMazeDrawer
  7. {
  8. public:
  9. virtualvoidDrawMaze(Maze*maze)
  10. {
  11. for(inti=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::stringdir;
  18. for(intj=0;j<4;++j)
  19. {
  20. switch(j)
  21. {
  22. caseEast:
  23. dir="East";
  24. break;
  25. caseSouth:
  26. dir="South";
  27. break;
  28. caseWest:
  29. dir="West";
  30. break;
  31. caseNorth:
  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. classMazeGame
  7. {
  8. public:
  9. MazeGame(MazeDrawer*md=0)
  10. {
  11. _mazeDrawer=md;
  12. }
  13. virtualMaze*CreateMaze(MazeBuilder&mb)=0;
  14. voidDeleteMaze(Maze*maze)
  15. {}
  16. voidDrawMaze(Maze*maze)
  17. {
  18. if(_mazeDrawer!=0)
  19. _mazeDrawer->DrawMaze(maze);
  20. }
  21. private:
  22. MazeDrawer*_mazeDrawer;
  23. };
  24. classGame1:publicMazeGame
  25. {
  26. public:
  27. Game1(MazeDrawer*md):MazeGame(md){}
  28. virtualMaze*CreateMaze(MazeBuilder&mb)
  29. {
  30. for(inti=0;i<24;++i)
  31. mb.BuildRoom(i);
  32. mb.BuildDoor(0,1);
  33. mb.BuildDoor(1,2);
  34. mb.BuildDoor(2,10);
  35. mb.BuildDoor(10,11);
  36. mb.BuildDoor(11,12);
  37. mb.BuildDoor(12,20);
  38. mb.BuildDoor(20,21);
  39. mb.BuildDoor(21,22);
  40. mb.BuildDoor(22,14);
  41. mb.BuildDoor(14,15);
  42. returnmb.GetMaze();
  43. }
  44. };
  45. #endif

/

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值