设计模式中迷宫的实现,用于学习创建型模式
来源:互联网 发布:tgp网络出口不稳定 编辑:程序博客网 时间:2024/06/03 18:28
设计模式一书相信不少人看过。其中创建型模式一节通过一个创建迷宫的例子阐述了工厂模式、抽象工厂模式等创建型模式。对于初学者而言,书中讲解并未实现具体代码,对于几种设计模式的优势不能深刻的体会。出于学习的目的我实现了这个迷宫,并且尽量保持原书中的类结构,用于体会创建型模式的优点。代码并不难,详见注释。本源码中仅实现了抽象工厂模式,其他模式详见设计模式一书。注意启动RTTI,下图为运行效果。
以下源码为不使用创建型模式的实现。
#include <iostream>#include <Windows.h>#include <string.h>enum Direction{North,South,West,East};class Coor//在数组中的坐标{public: Coor(int v=0,int h=0):vertical(v),horizontal(h){} int vertical; int horizontal;};class MapSite{public:virtual void Enter()=0;};class Wall:public MapSite{public:virtual void Enter(){ std::cout<<"this is a Wall!"<<std::endl;}};class Room:public MapSite{public:Room(Coor r){m_linenumber=r.horizontal;m_rownumber=r.vertical;}MapSite* GetSide(Direction d) const{ return m_sides[d];}void SetSide(Direction d,MapSite* m){ m_sides[d]=m;}virtual void Enter(){ std::cout<<"You entered the room "<<m_rownumber<<","<<m_linenumber<<std::endl;}private:MapSite* m_sides[4];int m_linenumber;int m_rownumber;};class Door:public MapSite{public:Door(Room* r1= 0,Room* r2= 0,bool b=true){ m_room1=r1; m_room2=r2; m_isOpen=b;}virtual void Enter(){if(m_isOpen==true)std::cout<<"you went through the door."<<std::endl;elsestd::cout<<"the door is closed."<<std::endl;}Room* OtherSideFrom(Room* r){ if(r==m_room1) return m_room2; else return m_room1;}void setIsOpen(bool b){ m_isOpen=b;}bool getIsOpen(){ return m_isOpen;}private:Room* m_room1;Room* m_room2;bool m_isOpen;};class Person//迷宫中的人{public:Coor getPlace(){return m_place;}void setPlace(Coor place){ m_place=place;}private:Coor m_place;};class Maze//迷宫{public:Maze(int height=3,int width=3,Coor Place=Coor(0,0)){ m_height=height; m_width=width; m_rooms=new Room**[height]; memset(m_rooms,0,height*sizeof(Room**)); m_p.setPlace(Place);}void addRoom(Room* r,int h,int w){ if(w<0||w>=m_width||h<0||h>=m_height) return ; else { if (m_rooms[h]==NULL) m_rooms[h]=new Room*[m_width]; m_rooms[h][w]=r; }}Room* getRoom(int h,int w){ return m_rooms[h][w];}void pGoWest()//向左走{MapSite* m=m_rooms[m_p.getPlace().vertical][m_p.getPlace().horizontal]->GetSide(West);m->Enter();if(typeid(*m)==typeid(Room)){m_p.setPlace(Coor(m_p.getPlace().vertical,m_p.getPlace().horizontal-1));}else if(typeid(*m)==typeid(Door)){Door* r=dynamic_cast<Door*>(m);if(r->getIsOpen()==true){Room* ar=r->OtherSideFrom(m_rooms[m_p.getPlace().vertical][m_p.getPlace().horizontal]); m_p.setPlace(Coor(m_p.getPlace().vertical,m_p.getPlace().horizontal-1)); ar->Enter();}}return ;}void pGoEast()//向右走{MapSite* m=m_rooms[m_p.getPlace().vertical][m_p.getPlace().horizontal]->GetSide(East);m->Enter(); if(typeid(*m)==typeid(Room)){m_p.setPlace(Coor(m_p.getPlace().vertical,m_p.getPlace().horizontal+1));}else if(typeid(*m)==typeid(Door)){Door* r=dynamic_cast<Door*>(m);if(r->getIsOpen()==true){ Room* ar=r->OtherSideFrom(m_rooms[m_p.getPlace().vertical][m_p.getPlace().horizontal]); m_p.setPlace(Coor(m_p.getPlace().vertical,m_p.getPlace().horizontal+1)); ar->Enter();}}return ;}void pGoNorth()//向上走{MapSite* m=m_rooms[m_p.getPlace().vertical][m_p.getPlace().horizontal]->GetSide(North);m->Enter(); if(typeid(*m)==typeid(Room)){m_p.setPlace(Coor(m_p.getPlace().vertical+1,m_p.getPlace().horizontal));}else if(typeid(*m)==typeid(Door)){Door* r=dynamic_cast<Door*>(m);if(r->getIsOpen()==true){ Room* ar=r->OtherSideFrom(m_rooms[m_p.getPlace().vertical][m_p.getPlace().horizontal]); m_p.setPlace(Coor(m_p.getPlace().vertical-1,m_p.getPlace().horizontal)); ar->Enter();}}return ;}void pGoSouth()//向下走{MapSite* m=m_rooms[m_p.getPlace().vertical][m_p.getPlace().horizontal]->GetSide(South);m->Enter(); if(typeid(*m)==typeid(Room)){m_p.setPlace(Coor(m_p.getPlace().vertical+1,m_p.getPlace().horizontal));}else if(typeid(*m)==typeid(Door)){Door* r=dynamic_cast<Door*>(m);if(r->getIsOpen()==true){ Room* ar=r->OtherSideFrom(m_rooms[m_p.getPlace().vertical][m_p.getPlace().horizontal]); m_p.setPlace(Coor(m_p.getPlace().vertical+1,m_p.getPlace().horizontal)); ar->Enter();}}return ;}void PrintMaze()//打印当前迷宫状态{ HANDLE hconsole; hconsole=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hconsole,MAKEWORD(7,0)); for(int i=0;i<m_height;i++) { for(int j=0;j<m_width;j++) { if(m_p.getPlace().vertical==i&&m_p.getPlace().horizontal==j) { SetConsoleTextAttribute(hconsole,MAKEWORD(4,0)); printf("%c ",'P'); continue; } if(m_rooms[i][j]==NULL) { SetConsoleTextAttribute(hconsole,MAKEWORD(7,0)); } else SetConsoleTextAttribute(hconsole,MAKEWORD(3,0)); printf("%d ",j); } printf("\n"); }}private:int m_height;int m_width;Room*** m_rooms;//二位数组,每个元素是一个指向Room的指针。Person m_p;};class MazeGame{public:void CreateMaze();void startGame();private:Maze *m_maze;};void MazeGame::startGame(){m_maze->PrintMaze();char c;while(std::cin.get(c)){ if(c=='w'){m_maze->pGoNorth();m_maze->PrintMaze();}if(c=='s'){m_maze->pGoSouth();m_maze->PrintMaze();}if(c=='a'){m_maze->pGoWest();m_maze->PrintMaze();}if(c=='d'){m_maze->pGoEast();m_maze->PrintMaze();}}}void MazeGame::CreateMaze(){Maze* aMaze=new Maze(2,5);Room* r1=new Room(Coor(0,0));Room* r2=new Room(Coor(0,1));Room* r3=new Room(Coor(0,2));Room* r4=new Room(Coor(0,3));Room* r5=new Room(Coor(0,4));Room* r6=new Room(Coor(1,0));Room* r7=new Room(Coor(1,1));Room* r8=new Room(Coor(1,2));Room* r9=new Room(Coor(1,3));Room* r10=new Room(Coor(1,4));Door* door1=new Door(r1,r2);Door* door2=new Door(r2,r3);Door* door3=new Door(r3,r4,false);Door* door4=new Door(r4,r5);Door* door10=new Door(r6,r7);Door* door11=new Door(r7,r8);Door* door12=new Door(r8,r9);Door* door13=new Door(r9,r10,false);Door* door5=new Door(r1,r6,false);Door* door6=new Door(r2,r7);Door* door7=new Door(r3,r8,false);Door* door8=new Door(r4,r9);Door* door9=new Door(r5,r10);aMaze->addRoom(r1,0,0);aMaze->addRoom(r2,0,1);aMaze->addRoom(r3,0,2);aMaze->addRoom(r4,0,3);aMaze->addRoom(r5,0,4);aMaze->addRoom(r6,1,0);aMaze->addRoom(r7,1,1);aMaze->addRoom(r8,1,2); aMaze->addRoom(r9,1,3);aMaze->addRoom(r10,1,4);r1->SetSide(North,new Wall);r1->SetSide(South,door5);r1->SetSide(West,new Wall);r1->SetSide(East,door1);r2->SetSide(North,new Wall);r2->SetSide(South,door6);r2->SetSide(West,door1);r2->SetSide(East,door2);r3->SetSide(North,new Wall);r3->SetSide(South,door7);r3->SetSide(West,door2);r3->SetSide(East,door3);r4->SetSide(North,new Wall);r4->SetSide(South,door8);r4->SetSide(West,door3);r4->SetSide(East,door4);r5->SetSide(North,new Wall);r5->SetSide(South,door9);r5->SetSide(West,door4);r5->SetSide(East,new Wall);r6->SetSide(North,door5);r6->SetSide(South,new Wall);r6->SetSide(West,new Wall);r6->SetSide(East,door10);r7->SetSide(North,door6);r7->SetSide(South,new Wall);r7->SetSide(West,door10);r7->SetSide(East,door11);r8->SetSide(North,door7);r8->SetSide(South,new Wall);r8->SetSide(West,door11);r8->SetSide(East,door12);r9->SetSide(North,door8);r9->SetSide(South,new Wall);r9->SetSide(West,door12);r9->SetSide(East,door13);r10->SetSide(North,door9);r10->SetSide(South,new Wall);r10->SetSide(West,door13);r10->SetSide(East,new Wall); m_maze=aMaze;}int main(){ std::cout<<"按wsad进行操作,ctrl+z退出。\n"; MazeGame ng; ng.CreateMaze(); ng.startGame(); return 0;}
使用创建型模式,仅需要做少量更改:
class MazeFactory{public:MazeFactory(){}; virtual Maze* MakeMaze(int height,int width,Coor coor) const { return new Maze(height,width,coor); } virtual Wall* MakeWall() const { return new Wall; } virtual Room* MakeRoom(Coor coor) const { return new Room(coor); } virtual Door* MakeDoor(Room* r1,Room* r2,bool b) const { return new Door(r1,r2,b); }};
void MazeGame::CreateMaze(MazeFactory& factory){Maze* aMaze=factory.MakeMaze(2,5,Coor(0,0));Room* r1=factory.MakeRoom(Coor(0,0));Room* r2=factory.MakeRoom(Coor(0,1));Room* r3=factory.MakeRoom(Coor(0,2));Room* r4=factory.MakeRoom(Coor(0,3));Room* r5=factory.MakeRoom(Coor(0,4));Room* r6=factory.MakeRoom(Coor(1,0));Room* r7=factory.MakeRoom(Coor(1,1));Room* r8=factory.MakeRoom(Coor(1,2));Room* r9=factory.MakeRoom(Coor(1,3));Room* r10=factory.MakeRoom(Coor(1,4));Door* door1=factory.MakeDoor(r1,r2,true);Door* door2=factory.MakeDoor(r2,r3,true);Door* door3=factory.MakeDoor(r3,r4,false);Door* door4=factory.MakeDoor(r4,r5,true);Door* door10=factory.MakeDoor(r6,r7,true);Door* door11=factory.MakeDoor(r7,r8,true);Door* door12=factory.MakeDoor(r8,r9,true);Door* door13=factory.MakeDoor(r9,r10,false);Door* door5=factory.MakeDoor(r1,r6,false);Door* door6=factory.MakeDoor(r2,r7,true);Door* door7=factory.MakeDoor(r3,r8,false);Door* door8=factory.MakeDoor(r4,r9,true);Door* door9=factory.MakeDoor(r5,r10,true);aMaze->addRoom(r1,0,0);aMaze->addRoom(r2,0,1);aMaze->addRoom(r3,0,2);aMaze->addRoom(r4,0,3);aMaze->addRoom(r5,0,4);aMaze->addRoom(r6,1,0);aMaze->addRoom(r7,1,1);aMaze->addRoom(r8,1,2); aMaze->addRoom(r9,1,3);aMaze->addRoom(r10,1,4);r1->SetSide(North,factory.MakeWall());r1->SetSide(South,door5);r1->SetSide(West,factory.MakeWall());r1->SetSide(East,door1);r2->SetSide(North,factory.MakeWall());r2->SetSide(South,door6);r2->SetSide(West,door1);r2->SetSide(East,door2);r3->SetSide(North,factory.MakeWall());r3->SetSide(South,door7);r3->SetSide(West,door2);r3->SetSide(East,door3);r4->SetSide(North,factory.MakeWall());r4->SetSide(South,door8);r4->SetSide(West,door3);r4->SetSide(East,door4);r5->SetSide(North,factory.MakeWall());r5->SetSide(South,door9);r5->SetSide(West,door4);r5->SetSide(East,factory.MakeWall());r6->SetSide(North,door5);r6->SetSide(South,factory.MakeWall());r6->SetSide(West,factory.MakeWall());r6->SetSide(East,door10);r7->SetSide(North,door6);r7->SetSide(South,factory.MakeWall());r7->SetSide(West,door10);r7->SetSide(East,door11);r8->SetSide(North,door7);r8->SetSide(South,factory.MakeWall());r8->SetSide(West,door11);r8->SetSide(East,door12);r9->SetSide(North,door8);r9->SetSide(South,factory.MakeWall());r9->SetSide(West,door12);r9->SetSide(East,door13);r10->SetSide(North,door9);r10->SetSide(South,factory.MakeWall());r10->SetSide(West,door13);r10->SetSide(East,factory.MakeWall()); m_maze=aMaze;}
- 设计模式中迷宫的实现,用于学习创建型模式
- 《GOF设计模式》—创建型模式—Delphi源码示例:未基于模式的迷宫
- 《GOF设计模式》—创建型模式—Delphi源码示例:基于创建型模式的迷宫
- 基于创建型模式的“迷宫”构造
- 设计模式学习 - 创建型模式(1)
- 创建型模式-- 设计模式学习之一
- 设计模式学习总结-创建型模式
- 设计模式学习-创建型模式
- 创建型设计模式学习
- 设计模式学习-创建型
- 关于设计模式中创建型模式的一点理解
- ANDROID 中设计模式的采用--创建型模式
- ANDROID 中设计模式的采用--创建型模式
- 设计模式中创建型模式
- 设计模式中创建型模式 (二):原型模式
- 《设计模式》学习笔记(二):创建型模式。。我认识的第一个模式
- 设计模式学习之创建型模式学习总结
- [创建型设计模式:Builder]代码实现
- Job的处理结果输出格式化器——OutputFormat
- map任务执行中的Spill/Meger/Combiner
- 作业在map-reduce过程中的文件编码/解码
- 由浅入深理解索引的实现(1)
- 二维数组
- 设计模式中迷宫的实现,用于学习创建型模式
- JobTracker任务调度器之JobQueueTaskScheduler
- c# 给一个datatime型值 加减
- 在vs2010中检测 C++ 程序内存泄露
- asp.net几种页面传值的方式
- Job的提交——JobTracker
- Job的提交—客户端
- linux小记6 权限
- Hadoop公平调度器算法解析