目录
1. 模式简介
原型模式可以让我们在创建新的实例时,隐藏内部复杂性。
比如有时候我们在创建一个对象时,非常耗资源,可能要搜索数据库获取一些资料,或者是加载一个内存占用达几个G的重量级分词组件到内存中,亦或是构建一个需要很多算力资源的实例。如果是类似这些场景,那prototype模式是一个很好的选择。
主要思想其实比较简单:先用原型实例指定创建对象的种类,再通过拷贝这些原型,来创建新的对象。
Prototype模式提供了一个通过已存在对象进行新对象创建的接口(即Clone函数), Clone()实现和具体的语言相关,在C++中通过拷贝构造函数实现。
2. UML类图
按照GOF,各个角色的说明:
Prototype(抽象原型类)
声明一个克隆自身的接口。此角色负责定义用于复制现有实例来生成新实例的方法,即Clone()。
ConcretePrototype(具体原型类)
实现一个克隆自身的操作。此角色负责实现复制现有实例并生成新实例的方法。
Client(客户类/使用者)
让一个原型克隆自身从而创建一个新的对象。此角色负责使用复制实例的方法生成新的实例。
3. 代码实现
#include <iostream>
using namespace std;
//抽象原型类
class Prototype
{
public:
virtual Prototype* Clone() = 0;
virtual void Execute() = 0;
};
//原型实现类
class ConcretePrototype : public Prototype
{
public:
ConcretePrototype() {}
//拷贝构造
ConcretePrototype(const ConcretePrototype& rhs) {
cout << "copy construct() call" << endl;
}
virtual ~ConcretePrototype() {}
public:
Prototype* Clone() override {
return new ConcretePrototype(*this);
}
void Execute() override {
cout << "execute() done" << endl;
}
};
//客户类
class Client
{
public:
Client() {
_pt = new ConcretePrototype;
}
virtual ~Client() {}
void Operation() {
Prototype* pt = _pt->Clone();
pt->Execute();
}
private:
Prototype* _pt;
};
int main(int argc, char* argv[])
{
Client cli;
cli.Operation();
return 0;
}
运行结果为:
copy construct() call
execute() done
4. 总结
Prototype模式和Builder模式、AbstractFactory模式都是通过一个类(对象实例)来专门负责对象的创建工作(工厂对象),它们之间的区别是:Builder模式重在复杂对象的一步步创建(并不直接返回对象),AbstractFactory模式重在产生多个相互依赖类的对象,而Prototype模式重在从自身复制自己创建新类。