设计模式之对象创建型 — prototype 原型模式

来源:互联网 发布:网络搞笑证件图片大全 编辑:程序博客网 时间:2024/06/10 13:05

本系列博客示例代码均为C++代码,个人之言,请持怀疑态度参考。如有错误,欢迎留言指正。

什么是原型模式

创建一个应用需要由很多组件构成,原型模式旨在通过给工厂传递原型实例,让后工厂通过拷贝构造这些原型来组件应用。
举个例子:在abstract模式中有贪吃蛇游戏的例子。他每实现一种模式,都需要写一个snakeFactory的子类。如果用原型模式的话则不需要创建辣么多子类,通过传递不同的原型就可以了。


示例代码

示例代码有点长,建议把代码直接拷贝到VS项目中调试 。

//maze.h文件 #ifndef MAZE_H#define MAZE_H#include <iostream>using namespace std;/************************************************************************//* 这是一个简单的迷宫游戏的例子,代码只是示意设计模式                                                                     *//************************************************************************///迷宫类class Maze{public:    Maze();    ~Maze();    Maze(const Maze &);  //拷贝构造  这里需要用深拷贝,而不是使用默认的拷贝构造函数    virtual Maze* clone();  //克隆函数,一些克隆出实例的一个副本 并且返回其指针      virtual void dis();  private:};//房间类class Room{public:    Room();    ~Room();    Room(Room & other);    virtual Room* clone();    virtual void dis();private:};//墙壁类  缺省为墙壁1号,也是墙壁的基类;这个可以根据实际设计,也可以写成一个抽象类class Wall{public:    Wall();    ~Wall();    Wall(Wall &other);    virtual Wall* clone();    virtual void dis();private:};//继承墙壁1号  并且改进 成为 墙壁2号  class Wall_2:public Wall{public:    Wall_2();    ~Wall_2();    //子类必须重新实现Clone 并实现相应的拷贝构造器    Wall_2(const Wall_2 &other);    Wall *clone();    void init(int a,int b);   //初始化并非必须的,根据情况实现    void dis();private:};//迷宫的抽象工厂class MazeFactory{public:    MazeFactory();    ~MazeFactory();    virtual Wall* makeWall() const=0;    virtual Room *makeRoom() const=0;    virtual Maze *makeMaze() const = 0;private:};class Pro_MazeFactory: public MazeFactory{public:    Pro_MazeFactory();    ~Pro_MazeFactory();    /*以原型为参数的构造器*/    Pro_MazeFactory(Wall*, Room *,Maze *);    /*重写基类方法*/    Wall* makeWall() const;    Room *makeRoom() const;    Maze *makeMaze() const;private:    Wall * _pro_wall;    Room *_pro_room;    Maze *_pro_maze;};//客户的类,用来组织游戏逻辑  class Game{public:    Game();    ~Game();    Maze * creat_game(MazeFactory& factory);private:};#endif//maze.cpp文件#include "maze.h"MazeFactory::MazeFactory(){}MazeFactory::~MazeFactory(){}Room::Room(){}Room::Room(Room & other){    /**拷贝构造的代码**/}Room* Room::clone(){    return new Room(*this); }void Room::dis(){    cout << "我是房间1号" << endl;}Room::~Room(){}Wall::Wall(){}Wall::Wall(Wall &other){    /**拷贝构造的代码**/}Wall* Wall::clone(){    return new Wall(*this);}void Wall::dis(){    cout << "我是Wall 1号" << endl;}Wall::~Wall(){}Maze::Maze(){}Maze::Maze(const Maze &){    /**拷贝构造的代码**/}Maze::~Maze(){}Maze* Maze::clone(){    return new Maze(*this);  //调用拷贝构造器}void Maze::dis(){    cout << "我是迷宫1号" << endl;}Wall_2::Wall_2(){}Wall_2::Wall_2(const Wall_2 &other){    /****/}Wall * Wall_2::clone(){    return new Wall_2(*this);}Wall * Wall_2::init(int a,int b){    /*做一些初始化工作*/}Wall_2::~Wall_2(){}void Wall_2::dis(){    cout << "我是墙壁2号" << endl;}Game::Game(){}Game::~Game(){}Maze * Game::creat_game(MazeFactory& factory){    Maze *amaze=factory.makeMaze();    Room *room = factory.makeRoom();    Wall* wall = factory.makeWall();    /* 其他的逻辑代码   */    amaze->dis();    room->dis();    wall->dis();    return amaze;}Pro_MazeFactory::Pro_MazeFactory(){}Pro_MazeFactory::Pro_MazeFactory(Wall* w, Room * r,Maze *m){    _pro_room = r;    _pro_wall = w;    _pro_maze = m;}Wall* Pro_MazeFactory::makeWall() const{    return _pro_wall->clone();}Room * Pro_MazeFactory::makeRoom() const{    return _pro_room->clone();}Maze * Pro_MazeFactory::makeMaze() const{    return _pro_maze->clone();}Pro_MazeFactory::~Pro_MazeFactory(){}//main.cpp文件 #include <iostream>using namespace std;#include "maze.h"int main(){    Game game;    Pro_MazeFactory factory(new Wall, new Room, new Maze);  //传递原型实例给工厂  这是第一种组合  迷宫1号 墙壁1号  房间1号     Maze* m = game.creat_game(factory);    cout << "---完美分割线----" << endl;    Pro_MazeFactory factory_2(new Wall_2, new Room, new Maze); //传递原型实例给工厂  这是第二种组合  迷宫1号 墙壁2号  房间1号     Maze *m_2 = game.creat_game(factory_2);    getchar();    return 0;}

提示:示例代码是没有提供 内存释放的方法的 也就是说这份代码是有内存泄漏的缺陷,不过作为示例代码,旨在理解何为原型模式。如果在实际项目中 必须提供释放内存的代码 。


适用性

  • 当实力化的类是在运行时刻指定时,比如通过动态装载。
  • 当一个类的实例只能有几种不同的状态组合中的一种时。

效果

原型模式的效果有很多是与abstract、builder重叠的
他的一些独特的特点 :

  • 可以动态的增删在运行时刻
  • 无需通过新建子类就可以得到新的类,极大的减少了系统所需要类的数目。
  • 允许实例化复杂的、用户定义的结构。比如,每次多次使用的特定子电路,游戏中多次使用的特定场景等。

实现

实现在代码中已经做过注释了,可以做如下概括:

  • 实现克隆操作
  • 初始化克隆对象
  • 使用一个原型管理器,当系统中的原型数目不确定时,要保持一个可用原型的注册表。这个在代码示例中并没实现,自己根据需要实现就可以了。

我的个人网站 http://www.breeziness.cn/
我的CSDN http://blog.csdn.net/qq_33775402

转载请注明出处 小风code www.breeziness.cn

阅读全文
0 0