本系列博客示例代码均为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