5.原型模式

2026-01-22
1033 字 · 5 分钟

设计模式——原型模式

一、基本概念

1. 定义

原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”,这个原型是可定制的。

原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效;或者创建值相等,只是命名不一样的同类数据。

2. 优缺点

优点

  • C++ 中原型模式基于拷贝构造函数复制对象,无需重新执行完整的构造初始化流程,在性能上往往更加优良;
  • 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。

缺点

  • 需要为每一个类都配置一个 clone 方法;
  • clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则;
  • 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。

3. 结构

原型模式包含以下主要角色。

  • 抽象原型类:规定了具体原型对象必须实现的接口;
  • 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象;
  • 访问类:使用具体原型类中的 clone() 方法来复制新的对象。

4. UML

C++ 中没有统一的根基类,惯用法是在抽象基类中声明虚函数 clone(),具体原型类利用拷贝构造函数实现它,这里的抽象基类就是抽象原型类。

classDiagram class Prototype { <<abstract>> +clone() Prototype } class ConcretePrototype { +clone() Prototype } class Client { +operation() void } Prototype <|-- ConcretePrototype Client ..> Prototype : clone() 复制

二、代码实现

原型模式的克隆分为浅克隆和深克隆。

  • 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于指针类型的成员,仍指向原有属性所指向的内存地址;
  • 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

浅克隆

浅克隆使用拷贝构造函数实现即可。

#include <iostream>
#include <vector>
class ConcretePrototype {
/*
* 具体原型类
* */
public:
// C++ 中利用拷贝构造函数实现克隆(对应 Java 的 clone())
ConcretePrototype* clone() const {
return new ConcretePrototype(*this);
}
};
int main() {
/*
* 实现类
* */
ConcretePrototype concretePrototype;
std::vector<ConcretePrototype*> list;
for (int i = 0; i < 10; i++) {
list.push_back(concretePrototype.clone());
}
// 打印每个克隆对象的地址,可见是 10 个不同的新对象
for (const auto* p : list) {
std::cout << p << std::endl;
}
for (auto* p : list) {
delete p;
}
return 0;
}

深克隆

深克隆一般情况下都是通过自定义拷贝构造函数实现(逐成员复制所引用的对象)。

#include <iostream>
#include <string>
class Target {
// 需要被深拷贝的类
public:
std::string name;
explicit Target(std::string name) : name(std::move(name)) {}
};
class ConPrototype {
/*
* C++ 中通过拷贝构造函数实现深克隆:
* 成员 target 会被完整复制为新的对象,而非与原对象共享
* */
private:
Target target{"小红"}; // 等价于 Java 的 private Target target = new Target("小红");
public:
ConPrototype* deepClone() const {
// 调用拷贝构造函数,成员被逐层复制(深拷贝)
return new ConPrototype(*this);
}
const Target& getTarget() const {
return target;
}
};
int main() {
ConPrototype obj;
ConPrototype* obj1 = obj.deepClone();
// 比较:深克隆后两个 target 是不同的对象
std::cout << std::boolalpha
<< (&obj.getTarget() == &obj1->getTarget()) << std::endl;
delete obj1;
return 0;
}

参考:


Thanks for reading!

5.原型模式

2026-01-22
1033 字 · 5 分钟

已复制链接

评论区

目录