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

本系列博客示例代码均为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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值