四、Prototype(原型)
情景举例:
创建一个可重用的建造迷宫程序。
代码示例:
/* 原型工厂继承自抽象工厂类 */ 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; } /* 现在各操作都使用Clone来实现 */ 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); /* */ } void dummy2 () { /* */ MazePrototypeFactory bombedMazeFactory( new Maze, new BombedWall, new RoomWithABomb, new 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* _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 { 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); }
个人理解:
原型方法是基于抽象工厂的一个扩展。在原型工厂的构造函数中将需要能够动态改变的变量(即墙壁、房间和门)暴露给用户(例子中主程序的MazePrototypeFactory实例)。而在实现的时候使用这些变量的克隆操作(显然,传入的变量要能够支持克隆操作)。真正的难点在于如何让这些变量支持克隆操作(例子中的比较简单)。