设计模式之原型法(ProtoType)----对象创建型模式
1.意图
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2.适用性
1)当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者
2)为了避免创建一个与产品类层次平行的工厂类层次时;或者
3)当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
3.结构
4.参与者
*Prototype
---声明一个Clone自身的接口。
*ConcretePrototype
---实现一个Clone自身的操作。
Client
---让一个原型Clone自身从而创建一个新的对象。
5.协作
客户请求一个原型Clone自身。
6.例子:
/**********************************************************
*
*
*
* 生成一个游戏迷宫
*
*
**************************************************************/
class MazePrototypeFactory : public MazeFactory {
public:
MazePrototypeFactory(Maze*, Wall*, Room*, Door*);
virtual Maze* MakeMaze() const;
virtual Room* MakeRoom(int) const;
virtual Wall* MakeWall() const;
virtual Door* MakeDoor(Room*, Room*) const;
private:
Maze* _prototypeMaze;
Room* _prototypeRoom;
Wall* _prototypeWall;
Door* _prototypeDoor;
};
MazePrototypeFactory::MazePrototypeFactory (
Maze* m, Wall* w, Room* r, Door* d
) {
_prototypeMaze = m;
_prototypeWall = w;
_prototypeRoom = r;
_prototypeDoor = d;
}
Wall* MazePrototypeFactory::MakeWall () const {
return _prototypeWall->Clone();
}
Door* MazePrototypeFactory::MakeDoor (Room* r1, Room *r2) const {
Door* door = _prototypeDoor->Clone();
door->Initialize(r1, r2);
return door;
}
void dummy () {
MazeGame game;
MazePrototypeFactory simpleMazeFactory(
new Maze, new Wall, new Room, new Door
); //生成一个原型对象
Maze* maze = game.CreateMaze(simpleMazeFactory);//完成自身的Clone
}
/*为了改变迷宫的类型,我们用一个不同的原型集合来初始化MazeProtetypeFactory。下面调用一个BombedDoor一个RomWithAbomb创建一个迷宫:*/
void dummy2 () {
MazePrototypeFactory bombedMazeFactory(
new Maze, new BombedWall,
new RoomWithABomb, new Door
);
}
class Door : public MapSite {
public:
Door();
Door(const Door&);
virtual void Initialize(Room*, Room*);
virtual Door* Clone() const;
virtual void Enter();
Room* OtherSideFrom(Room*);
private:
Room* _room1;
Room* _room2;
};
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 {
//一个ConcretePrototype的Clone函数
return new Door(*this);
}
class BombedWall : public Wall {
public:
BombedWall();
BombedWall(const BombedWall&);
virtual Wall* Clone() const;
bool HasBomb();
private:
bool _bomb;
};
BombedWall::BombedWall (const BombedWall& other) : Wall(other) {
_bomb = other._bomb;
}
Wall* BombedWall::Clone () const {
return new BombedWall(*this);
}