原型模式是一种创建型设计模式,其核心思想是通过复制现有对象来创建新对象,而无需通过标准的构造函数来创建。这种模式通常用于创建成本较高或复杂的对象,以提高性能和减少资源消耗。
设计原理:
基于复制: 原型模式基于对象的复制来创建新对象,而不是使用常规的构造函数。
原型对象: 原型对象作为一个模板,包含了需要复制的基本结构和数据。
克隆操作: 通过克隆操作创建新对象,可以是浅拷贝或深拷贝,具体取决于对象中包含的数据结构。
注册表: 有时,原型对象可以注册在一个原型管理器中,客户端可以从管理器中获取需要的原型对象。
特点:
减少对象创建成本: 避免了重复地执行构造函数的开销,特别适用于创建成本高昂的对象。
简化对象创建: 通过复制现有对象,简化了新对象的创建过程,提高了系统的灵活性和可扩展性。
动态配置: 可以在运行时动态地配置原型对象,实现不同的对象组合。
隐藏细节: 客户端只需知道如何获取原型对象,并不需要了解对象的创建细节。
以下是一个简单的c++实现:
#include <iostream>
#include <string>
#include <unordered_map>
// 抽象原型类
class Prototype {
public:
virtual ~Prototype() {}
virtual Prototype* clone() const = 0;
virtual void display() const = 0;
};
// 具体原型类 A
class ConcretePrototypeA : public Prototype {
public:
Prototype* clone() const override {
return new ConcretePrototypeA(*this); // 使用复制构造函数进行浅拷贝
}
void display() const override {
std::cout << "ConcretePrototypeA" << std::endl;
}
};
// 具体原型类 B
class ConcretePrototypeB : public Prototype {
public:
Prototype* clone() const override {
return new ConcretePrototypeB(*this); // 使用复制构造函数进行浅拷贝
}
void display() const override {
std::cout << "ConcretePrototypeB" << std::endl;
}
};
// 原型管理器
class PrototypeManager {
public:
// 注册原型对象
void registerPrototype(const std::string& name, Prototype* prototype) {
prototypes[name] = prototype;
}
// 获取原型对象
Prototype* getPrototype(const std::string& name) {
if (prototypes.find(name) != prototypes.end()) {
return prototypes[name]->clone(); // 返回原型对象的克隆
}
return nullptr;
}
private:
std::unordered_map<std::string, Prototype*> prototypes;
};
int main() {
// 创建原型管理器
PrototypeManager manager;
// 创建具体原型对象
ConcretePrototypeA prototypeA;
ConcretePrototypeB prototypeB;
// 注册原型对象
manager.registerPrototype("A", &prototypeA);
manager.registerPrototype("B", &prototypeB);
// 使用原型管理器获取原型对象
Prototype* cloneA = manager.getPrototype("A");
Prototype* cloneB = manager.getPrototype("B");
// 显示原型对象类型
if (cloneA) {
cloneA->display(); // ConcretePrototypeA
delete cloneA;
}
if (cloneB) {
cloneB->display(); // ConcretePrototypeB
delete cloneB;
}
return 0;
}
这个例子中,我们创建了两个具体的原型对象 ConcretePrototypeA 和 ConcretePrototypeB,并将它们注册到了原型管理器 PrototypeManager 中。客户端通过原型管理器获取需要的原型对象,并通过克隆操作创建新对象。