简单介绍
原型模式是一种创建型设计模式 | 它使你能够复制已有对象,客户端不需要知道要复制的对象是哪个类的实例,只需通过原型工厂获取该对象的副本。 以后需要更改具体的类或添加新的原型类,客户端代码无需改变,只需修改原型工厂即可 。
基础理解
Q:为什么使用原型模式
A:如果你有一个对象, 并希望生成与其完全相同的一个复制品。如果直接复制:
- 对方可能有私有成员变量(你无法访问私有)
- 不知道对方的具体类(可能使用父类接口,但我们需要复制的是具体子类)
解决方案
- 那我们在外部无法克隆,便可以想想在类的内部设置一个通用的克隆接口。对象可以访问同类对象的私有
- 克隆返回的对象的配置要与预先的配置相同。甚至有时候当构造函数变量很多几十个,克隆可以完全代替子类构造函数
UML 图
原型注册表 (Prototype Registry) 最简单的注册表原型是一个 名称 → 原型的哈希表。
实现步骤
- 创建原型接口, 并在其中声明 克隆方法。 如果你已有类层次结构, 则只需在其所有类中添加该方法即可。
- 原型类必须另行定义一个以该类对象为参数的构造函数。如果你需要修改子类,贼需要调用父类构造函数,让父类复制变量与子类保持一致。
- 克隆方法通常只有一行代码
newConcretePrototype1(*this);
每个类都必须显式重写克隆方法并使用自身类名调用 new运算符。 - 还可以创建一个原型注册表, 用于存储常用原型。将对子类构造函数的直接调用替换为对原型注册表的调用。
#include <iostream>
#include <string>
#include <unordered_map>
using std::string;
enum Type //枚举类
{
PROTOTYPE_1 = 0,
PROTOTYPE_2
};
//抽象原型类
class Prototype
{
protected:
string prototype_name_;
float prototype_field_;
public:
Prototype() {
}
Prototype(string prototype_name)
: prototype_name_(prototype_name)
{
}
virtual ~Prototype() {
}
virtual Prototype *Clone