创建型模式--原型

1、意图

用原型示例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

2、结构

 

 3、参与者

Prototype——声明一个克隆自身的接口;

ConcretePrototype——实现一个克隆自身的操作;

Client——让一个原型克隆自身从而创建一个新的对象;

4、适用性

当一个系统应该独立于他的产品创建、构成和表示时,要使用Prototype模式;

以及当要实例化的类是在运行时刻指定时,例如,通过动态装载;

为了避免创建一个与产品类层次平行的工厂类层次时;

当一个类的实例只能由几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

5、代码示例

// 迷宫类(即上述图示中的Client),利用原型对象组件构建迷宫
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;
}
// 利用基本迷宫构件的原型进行初始化,从而由MazePrototypeFactory构建一个原型的缺省的迷宫
MazeGame game;
MazePrototypeFactory simpleMazeFactory(new Maze, new Wall, new Room, new Door);
Maze* maze = game.CreateMaze(simpleMazeFactory);

// 为了改变迷宫的类型,利用不同的原型集合来初始化MazePrototypeFactory
MazePrototypeFactory bombedMazeFactory(new Maze, new BombedWall, new RoomwithABomb, new Door);
// 一个可以被用作原型的对象,例如Door的实例,必须支持Clone操作。
// 它还必须有一个拷贝构造器用于克隆,还需要一个独立的操作来重新初始化内部状态
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* _rooml; Room* _room2;
};

Door::Door(const Door& other)
{
    _rooml = other._room1;
    _room2 = other._room2;
}
void Door::Initialize(Room* r1, Room* r2)
{
    _roomi = r1;
    _room2 = r2;
}

Door* Door::Clone() const
{
    return new Door(*this);
}
// BombedWall子类必须重定义Clone并实现相应的拷贝构造器。
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);
}

 6、总结

  原型模式强调从自身复制自身,创建一个与自己一模一样的对象。原型基类需要定义Clone操作,而继承原型的子类都要实现Clone操作,以及重写拷贝构造函数,供Clone操作调用。原型模式适用于运行期间的拷贝需求,以及获取对象在某个状态下的副本需求。

posted @ 2022-04-09 18:03  流翎  阅读(33)  评论(0编辑  收藏  举报