您的位置:首页 > 其它

设计模式中创建型模式 (二):原型模式

2008-04-17 13:03 190 查看
Prototype(原型模式)
简单的讲,就是一种克隆模式,使得一个系统独立于它的产品的创建、构成和表示。
它有和Abstract Factory和Builder一样的效果:它对客户隐藏了具体的产品类。另外,Prototype模式还有另外一些优点:
1、运行时刻增加和删除产品
2、用类动态配置应用。
它的主要缺陷是每一个Prototype的子类都必需实现Clone操作,这可能很困难。例如,当所考虑的类已经存在时就难以新增Clone操作。
当内部包括一些不支持拷贝或有循环引用的对象时,实现克隆可能也会很困难的。
我们将定义MazeFactory的子类MazePrototypeFactory.该子类将使用它要创建的对象的原型来为初始化,这样我们就不需要仅仅为了改变它所
创建的墙壁或房间的类而生子类了。



以下为示例代码:(VC6+sp6)下测试通过




//MapSite.h


#pragma warning(disable: 4786)






#include <vector>


#include <map>


#include <iostream>


using namespace std;






//##ModelId=48059C280115


enum Direction




...{


North, South, East, West


};






/**///////////////////////////////////////////////////////////////////////////


//申明所有类


class Door;


class MapSite;


class Maze;


class MazeBuilder;


class MazeFactory;


class MazeGame;


class Room;


class StandardMazeBuilder;


class Wall;


class MazePrototypeFactory;




/**///////////////////////////////////////////////////////////////////////////




//##ModelId=48059C2800E6


class MapSite




...{


public:


//##ModelId=48059C280105


virtual void Enter() = 0;


};




//##ModelId=48059C280172


class Wall: public MapSite




...{


public:


//##ModelId=48059C280183




Wall()...{}




virtual Wall* Clone() const;




//##ModelId=48059C280184




virtual void Enter()...{printf("Wall::Enter() "); }


};






//##ModelId=48059C280134


class Room: public MapSite




...{


public:


//##ModelId=48059C280144




Room (int roomNo = 0)...{ _roomNumber = roomNo; }


//##ModelId=48059C280146




MapSite* GetSide(Direction d)const...{ return _sides[d]; }


//##ModelId=48059C280154




void SetSide (Direction d, MapSite* s)...{ _sides[d] = s; }





Room(const Room& other);


virtual Room* Clone();


virtual void Initialize(int n);


//##ModelId=48059C280157




virtual void Enter()...{ printf("Room::Enter() "); }





//##ModelId=48059C280159




int GetRoomNo()const...{ return _roomNumber; }


private:


//##ModelId=48059C280164


MapSite* _sides[4];


//##ModelId=48059C280168


int _roomNumber;


};




//##ModelId=48059C280191


class Door: public MapSite




...{


public:


//##ModelId=48059C2801A1




Door(Room* r1= 0, Room* r2= 0)...{ _room1 = r1;_room2 = r2; }




Door(const Door& other);





virtual void Initialize(Room *r1, Room* r2);


virtual Door* Clone() const;


//##ModelId=48059C2801A4




virtual void Enter()...{ printf("Door::Enter() "); };


//##ModelId=48059C2801A6


Room* OtherSideFrom(Room*);


private:


//##ModelId=48059C2801A9


Room * _room1;


//##ModelId=48059C2801B2


Room * _room2;


//##ModelId=48059C2801B6


bool _isOpen;


};




//##ModelId=48059C2801C0


class Maze




...{


public:


//##ModelId=48059C2801D0




Maze()...{ }





Maze(const Maze& other);


virtual Maze* Clone();




//##ModelId=48059C2801D1


void AddRoom(Room* r)




...{


maproom[r->GetRoomNo()] = r;


}


//##ModelId=48059C2801D3




Room* RoomNo(int no)...{ return maproom[no]; }





private:


//##ModelId=48059C2801EF


map<int, Room*> maproom;


//


};






//建造迷宫的程序将MazeFactory作为一个参数,这样程序员就能指定要创建的房间,


//墙壁和门等类


//##ModelId=48059C2801FF


class MazeFactory




...{


public:


//##ModelId=48059C280200




MazeFactory()...{}





//##ModelId=48059C280201


virtual Maze* MakeMaze()const




...{


return new Maze;


}


//##ModelId=48059C280203


virtual Wall* MakeWall()const




...{


return new Wall;


}


//##ModelId=48059C28020F


virtual Room* MakeRoom(int n)const




...{


return new Room(n);


}


//##ModelId=48059C280212


virtual Door* MakeDoor(Room* r1, Room* r2)const




...{


return new Door(r1, r2);


}


};






//创建各个部件,作用类似于MazeGame::CreateMaze();


//##ModelId=48059C28021E


class MazeBuilder




...{


public:


//##ModelId=48059C28021F




virtual void BuildMaze()...{}


//##ModelId=48059C280221




virtual void BuildRoom(int room)...{}


//##ModelId=48059C28022F




virtual void BuildDoor(int roomFrom,int roomTo)...{}




//##ModelId=48059C280233




virtual Maze* GetMaze()...{ return 0; }


protected:


//##ModelId=48059C280235




MazeBuilder()...{}




};




class StandardMazeBuilder: public MazeBuilder




...{


public:




StandardMazeBuilder()...{ _currentMaze = 0; }






virtual void BuildMaze()...{ _currentMaze = (Maze*) new StandardMazeBuilder; }


virtual void BuildRoom(int);


virtual void BuildDoor(int,int);






virtual Maze* GetMaze()...{ return _currentMaze; }


private:


Direction CommonWall(Room*, Room*);//决定哪两个相邻的墙可以有门。


Maze* _currentMaze;


};






//创建迷宫的类


//##ModelId=48059C28023D


class MazeGame: public Maze




...{


public:


//##ModelId=48059C28023F


Maze* CreateMaze();//普通方法创建迷宫,硬编码方式





//##ModelId=48059C28024D


Maze* CreateMaze2(MazeFactory& factory);//工厂类方式建造




Maze* CreateMaze3(StandardMazeBuilder& builder);//builder模式,建分部







Maze* CreateMaze4(MazePrototypeFactory& prototype);//原型模式


//##ModelId=48059C28024F


void printMaze()




...{


//好像比较麻烦


}


};






class MazePrototypeFactory: public MazeFactory




...{


public:


MazePrototypeFactory(Maze* m,Wall* w, Room* r, Door* d)




...{


_prototypeMaze = m;


_prototypeRoom = r;


_prototypeWall = w;


_prototypeDoor = d;


}




virtual Maze* MakeMaze() const;


virtual Room* MakeRoom(int n) const;


virtual Wall* MakeWall() const;


virtual Door* MakeDoor(Room* r1, Room* r2) const;




private:


Maze* _prototypeMaze;


Room* _prototypeRoom;


Wall* _prototypeWall;


Door* _prototypeDoor;


};




// MapSite.cpp : Defines the entry point for the console application.


//




#include "stdafx.h"




#include "MapSite.h"


Wall* Wall::Clone() const




...{


return new Wall(*this);


}






Room::Room(const Room& other)




...{


this->_roomNumber = other._roomNumber;


memcpy(this->_sides,other._sides,sizeof(_sides));


}


Room* Room::Clone()




...{


return new Room(*this);


}


void Room::Initialize(int n)




...{


this->_roomNumber = n;


}






Door::Door(const Door& other)




...{


_room1 = other._room1;


_room2 = other._room2;


}




void Door::Initialize(Room *r1, Room* r2)




...{


_room1 = r1;


_room2 = r2;


}




Door* Door::Clone() const




...{


return new Door(*this);


}




Maze::Maze(const Maze& other)




...{


maproom.clear();


//maproom.insert(other.maproom.begin(),other.maproom.end());


map<int, Room*>::const_iterator it;


it = other.maproom.begin();


for ( ;it != other.maproom.end(); it++)




...{


maproom.insert(*it);


}


}




Maze* Maze::Clone()




...{


return new Maze(*this);


}




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);


}




Direction StandardMazeBuilder::CommonWall(Room* r1, Room* r2)




...{


if(r1 == NULL || r2 == NULL )


return North;


if(r1->GetSide(North) == r2->GetSide(South))


return North;


if(r1->GetSide(South) == r2->GetSide(North))


return South;


if(r1->GetSide(West) == r2->GetSide(East))


return West;


if(r1->GetSide(East) == r2->GetSide(West))


return East;


return North;


}








//##ModelId=48059C28023F


Maze* MazeGame::CreateMaze()




...{


Maze* aMaze = new Maze;


Room* r1 = new Room(1);


Room* r2 = new Room(2);


Door* theDoor = new Door(r1,r2);





aMaze->AddRoom(r1);


aMaze->AddRoom(r2);





r1->SetSide(North, new Wall);


r1->SetSide(East, theDoor);


r1->SetSide(South, new Wall);


r1->SetSide(West, new Wall);








r2->SetSide(North, new Wall);


r2->SetSide(East, new Wall);


r2->SetSide(South, new Wall);


r2->SetSide(West, theDoor);





return aMaze;


}






//##ModelId=48059C28024D


Maze* MazeGame::CreateMaze2(MazeFactory& factory)




...{


Maze* aMaze = factory.MakeMaze();


Room* r1 = factory.MakeRoom(1);


Room* r2 = factory.MakeRoom(2);


Door* aDoor = factory.MakeDoor(r1, r2);





aMaze->AddRoom(r1);


aMaze->AddRoom(r2);





r1->SetSide(North, factory.MakeWall());


r1->SetSide(East, aDoor);


r1->SetSide(South, factory.MakeWall());


r1->SetSide(West, factory.MakeWall());





r2->SetSide(North, factory.MakeWall());


r2->SetSide(East, factory.MakeWall());


r2->SetSide(South, factory.MakeWall());


r2->SetSide(West, aDoor);


return aMaze;


}




Maze* MazeGame::CreateMaze3(StandardMazeBuilder& builder)




...{


builder.BuildMaze();




builder.BuildRoom(1);


builder.BuildRoom(2);


builder.BuildDoor(1, 2);




return builder.GetMaze();


}




Maze* MazeGame::CreateMaze4(MazePrototypeFactory& prototype)




...{


Maze* aMaze = prototype.MakeMaze();


Room* r1 = prototype.MakeRoom(1);


Room* r2 = prototype.MakeRoom(2);


Door* aDoor = prototype.MakeDoor(r1, r2);





aMaze->AddRoom(r1);


aMaze->AddRoom(r2);





r1->SetSide(North, prototype.MakeWall());


r1->SetSide(East, aDoor);


r1->SetSide(South, prototype.MakeWall());


r1->SetSide(West, prototype.MakeWall());





r2->SetSide(North, prototype.MakeWall());


r2->SetSide(East, prototype.MakeWall());


r2->SetSide(South, prototype.MakeWall());


r2->SetSide(West, aDoor);




return aMaze;


}




Maze* MazePrototypeFactory::MakeMaze() const




...{


return _prototypeMaze->Clone();


}




Wall* MazePrototypeFactory::MakeWall() const




...{


return _prototypeWall->Clone();


}




Room* MazePrototypeFactory::MakeRoom(int n) const




...{


Room* room = _prototypeRoom->Clone();


room->Initialize(n);


return room;


}




Door* MazePrototypeFactory::MakeDoor (Room* r1, Room* r2) const




...{


Door* door = _prototypeDoor->Clone();


door->Initialize(r1, r2);


return door;


}




// testMapSite.cpp : Defines the entry point for the console application.


//




#include "stdafx.h"


#include "MapSite.h"


int main(int argc, char* argv[])




...{


printf("Hello World! ");




MazeGame game;


MazePrototypeFactory simpleMazeFactory(new Maze, new Wall, new Room, new Door);


Maze* maze = game.CreateMaze4(simpleMazeFactory);


return 0;


}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: