本文在GOF《设计模式》一书“创建型模式”一章的例子和模式的基础上,将各个创建型模式有机的结合在一起。实现了“迷宫”构造过程的封装,增强了构造不同迷宫的可扩展性。
创建型模式:
抽象工厂
工厂方法
生成器
原型
单件
其中,抽象工厂是由工厂方法组成的,是一组相互关联的工厂方法的集合。
“迷宫”构造类图:
从类图中可以看出各个模式直接的关系,同时为了显示构造好的迷宫图案,还使用了“策略模式”用于画出迷宫(图中的MazeDrawer类层次)。
以下是各个模块的C++实现:
- #ifndef_PART_H_
- #define_PART_H_
- //Part.h
- enumDirection
- {
- East,
- South,
- West,
- North
- };
- classMapSite
- {
- public:
- virtualvoidEnter()=0;
- virtualchar*GetInfo()=0;
- };
- classRoom:publicMapSite
- {
- public:
- Room(introomNo)
- {
- _roomNo=roomNo;
- for(inti=0;i<4;++i)
- _sides[i]=0;
- }
- MapSite*GetSide(Directiond)const
- {
- return_sides[d];
- }
- voidSetSide(Directiond,MapSite*ms)
- {
- if(_sides[d]!=0)
- delete_sides[d];
- _sides[d]=ms;
- }
- virtualvoidEnter()
- {
- }
- virtualchar*GetInfo()
- {
- return"Room";
- }
- intRoomNo()const
- {
- return_roomNo;
- }
- private:
- MapSite*_sides[4];
- int_roomNo;
- };
- classWall:publicMapSite
- {
- public:
- Wall()
- {
- }
- virtualvoidEnter()
- {
- }
- virtualchar*GetInfo()
- {
- return"Wall";
- }
- };
- classDoor:publicMapSite
- {
- public:
- Door(Room*r1=0,Room*r2=0)
- {
- _room1=r1;
- _room2=r2;
- _isOpen=false;
- }
- Room*OtherSideFrom(Room*r)
- {
- if(r==_room1)
- return_room2;
- elseif(r==_room2)
- return_room1;
- return0;
- }
- virtualvoidEnter()
- {
- }
- virtualchar*GetInfo()
- {
- return"Door";
- }
- private:
- Room*_room1;
- Room*_room2;
- bool_isOpen;
- };
- classSpell
- {
- public:
- Spell()
- {}
- };
- classEnchantedRoom:publicRoom
- {
- public:
- EnchantedRoom(introomNo,Spell*spell):Room(roomNo)
- {
- _spell=spell;
- }
- virtualvoidEnter()
- {
- }
- virtualchar*GetInfo()
- {
- return"EnchantedRoom";
- }
- private:
- Spell*_spell;
- };
- classDoorNeedingSpell:publicDoor
- {
- public:
- DoorNeedingSpell(Room*r1,Room*r2):Door(r1,r2)
- {
- }
- virtualvoidEnter()
- {
- }
- virtualchar*GetInfo()
- {
- return"DoorNeedingSpell";
- }
- };
- classRoomWithABomb:publicRoom
- {
- public:
- RoomWithABomb(introomNo):Room(roomNo)
- {
- }
- virtualvoidEnter()
- {
- }
- virtualchar*GetInfo()
- {
- return"RoomWithABomb";
- }
- };
- classBombedWall:publicWall
- {
- public:
- BombedWall()
- {
- }
- virtualvoidEnter()
- {
- }
- virtualchar*GetInfo()
- {
- return"BombedWall";
- }
- };
- classMaze
- {
- public:
- Maze(intxsize=1,intysize=1)
- {
- if(xsize<=0||ysize<=0)
- {
- xsize=ysize=1;
- }
- _xsize=xsize;
- _ysize=ysize;
- _roomList=newRoom*[_xsize*_ysize];
- for(inti=0;i<_xsize*_ysize;++i)
- _roomList[i]=0;
- }
- voidAddRoom(Room*r)
- {
- intrno=r->RoomNo();
- _roomList[rno]=r;
- }
- Room*RoomNo(intrno)const
- {
- for(inti=0;i<_xsize*_ysize;++i)
- {
- if(_roomList[rno]==0)
- continue;
- if(_roomList[rno]->RoomNo()==rno)
- return_roomList[rno];
- }
- return0;
- }
- intXSize()const
- {
- return_xsize;
- }
- intYSzie()const
- {
- return_ysize;
- }
- intSize()const
- {
- return_xsize*_ysize;
- }
- ~Maze()
- {
- }
- private:
- Room**_roomList;
- int_xsize;
- int_ysize;
- };
- #endif
/
- //PartFactory.h
- #ifndef_PART_FACTORY_H_
- #define_PART_FACTORY_H_
- #include"Part.h"
- #include<string>
- classBombedPartFactory;
- classEnchantedPartFactory;
- classPartFactory
- {
- public:
- staticPartFactory*Instance();
- staticvoidSetMazeStyle(std::stringstyle)
- {
- _mazeStyle=style;
- }
- private:
- staticstd::string_mazeStyle;
- staticPartFactory*_instance;
- protected:
- PartFactory(){}
- public:
- virtualRoom*MakeRoom(intrno)const
- {
- returnnewRoom(rno);
- }
- virtualWall*MakeWall()const
- {
- returnnewWall();
- }
- virtualDoor*MakeDoor(Room*r1,Room*r2)const
- {
- returnnewDoor(r1,r2);
- }
- };
- classEnchantedPartFactory:publicPartFactory
- {
- public:
- EnchantedPartFactory(){}
- virtualRoom*MakeRoom(intrno)const
- {
- returnnewEnchantedRoom(rno,CastSpell());
- }
- virtualDoor*MakeDoor(Room*r1,Room*r2)const
- {
- returnnewDoorNeedingSpell(r1,r2);
- }
- protected:
- Spell*CastSpell()const
- {
- return0;
- }
- };
- classBombedPartFactory:publicPartFactory
- {
- public:
- BombedPartFactory(){}
- virtualRoom*MakeRoom(intrno)const
- {
- returnnewRoomWithABomb(rno);
- }
- virtualWall*MakeWall()const
- {
- returnnewBombedWall();
- }
- };
- #endif
//
- //PartFactory.cpp
- #include"PartFactory.h"
- PartFactory*PartFactory::_instance=0;
- std::stringPartFactory::_mazeStyle;
- PartFactory*PartFactory::Instance()
- {
- if(_instance==0)
- {
- if(_mazeStyle=="bombed")
- _instance=newBombedPartFactory();
- elseif(_mazeStyle=="enchanted")
- _instance=newEnchantedPartFactory();
- else
- _instance=newPartFactory();
- }
- return_instance;
- }
- //MazeBuilder.h
- #ifndef_MAZE_BUILDER_H_
- #define_MAZE_BUILDER_H_
- #include"PartFactory.h"
- classMazeBuilder
- {
- public:
- MazeBuilder()
- {
- BuildMaze();
- }
- voidBuildMaze()
- {
- _maze=newMaze(8,8);
- _factory=PartFactory::Instance();
- }
- Maze*GetMaze()
- {
- return_maze;
- }
- virtualvoidBuildRoom(intrno)
- {
- //emtpy
- }
- virtualvoidBuildDoor(introomFrom,introomTo)
- {
- //emtpy
- }
- protected:
- DirectionCommonWall(Room*r1,Room*r2)
- {
- intxs=_maze->XSize();
- Directiondir;
- if(r1->RoomNo()+1==r2->RoomNo())
- dir=East;
- if(r1->RoomNo()-1==r2->RoomNo())
- dir=West;
- if(r1->RoomNo()-xs==r2->RoomNo())
- dir=North;
- if(r1->RoomNo()+xs==r2->RoomNo())
- dir=South;
- returndir;
- }
- Maze*_maze;
- PartFactory*_factory;
- };
- classStdMazeBuilder:publicMazeBuilder
- {
- public:
- StdMazeBuilder(){}
- virtualvoidBuildRoom(intrno)
- {
- if(!_maze->RoomNo(rno))
- {
- Room*r=_factory->MakeRoom(rno);
- _maze->AddRoom(r);
- r->SetSide(North,_factory->MakeWall());
- r->SetSide(South,_factory->MakeWall());
- r->SetSide(East,_factory->MakeWall());
- r->SetSide(West,_factory->MakeWall());
- }
- }
- virtualvoidBuildDoor(introomFrom,introomTo)
- {
- Room*r1=_maze->RoomNo(roomFrom);
- Room*r2=_maze->RoomNo(roomTo);
- Door*d=_factory->MakeDoor(r1,r2);
- r1->SetSide(CommonWall(r1,r2),d);
- r2->SetSide(CommonWall(r2,r1),d);
- }
- };
- #endif
- //MazeDrawer.h
- #ifndef_MAZE_DRAW_H_
- #define_MAZE_DRAW_H_
- #include"Part.h"
- #include<iostream>
- classMazeDrawer
- {
- public:
- virtualvoidDrawMaze(Maze*maze)
- {
- for(inti=0;i<maze->Size();++i)
- {
- Room*r=maze->RoomNo(i);
- if(r!=0)
- {
- std::cout<<r->GetInfo()<<""<<r->RoomNo()<<"#:"<<std::endl;
- std::stringdir;
- for(intj=0;j<4;++j)
- {
- switch(j)
- {
- caseEast:
- dir="East";
- break;
- caseSouth:
- dir="South";
- break;
- caseWest:
- dir="West";
- break;
- caseNorth:
- dir="North";
- break;
- }
- std::cout<<""<<dir<<":"<<r->GetSide((Direction)j)->GetInfo()<<std::endl;
- }
- }
- }
- }
- };
- #endif
//
- //MazeGame.h
- #ifndef_MAZE_GAME_H_
- #define_MAZE_GAME_H_
- #include"MazeBuilder.h"
- #include"MazeDrawer.h"
- classMazeGame
- {
- public:
- MazeGame(MazeDrawer*md=0)
- {
- _mazeDrawer=md;
- }
- virtualMaze*CreateMaze(MazeBuilder&mb)=0;
- voidDeleteMaze(Maze*maze)
- {}
- voidDrawMaze(Maze*maze)
- {
- if(_mazeDrawer!=0)
- _mazeDrawer->DrawMaze(maze);
- }
- private:
- MazeDrawer*_mazeDrawer;
- };
- classGame1:publicMazeGame
- {
- public:
- Game1(MazeDrawer*md):MazeGame(md){}
- virtualMaze*CreateMaze(MazeBuilder&mb)
- {
- for(inti=0;i<24;++i)
- mb.BuildRoom(i);
- mb.BuildDoor(0,1);
- mb.BuildDoor(1,2);
- mb.BuildDoor(2,10);
- mb.BuildDoor(10,11);
- mb.BuildDoor(11,12);
- mb.BuildDoor(12,20);
- mb.BuildDoor(20,21);
- mb.BuildDoor(21,22);
- mb.BuildDoor(22,14);
- mb.BuildDoor(14,15);
- returnmb.GetMaze();
- }
- };
- #endif
/
- //MazeGame.cpp:定义控制台应用程序的入口点。
- //
- #include"stdafx.h"
- #include"MazeGame.h"
- int_tmain(intargc,_TCHAR*argv[])
- {
- PartFactory::SetMazeStyle("enchanted");
- MazeGame*game=newGame1(newMazeDrawer());
- Maze*maze=game->CreateMaze(StdMazeBuilder());
- game->DrawMaze(maze);
- return0;
- }
参考文献:GOF《设计模式》
希望通道中人提出意见建议,共同改善完善,共同交流:hm.y@live.cn