五大创建型设计模式:
单例模式,策略模式,观察者模式,工厂模式,原型模式
原型模式(Prototype Pattern)详解
原型模式是一种创建型设计模式,通过复制现有对象(原型)来创建新对象,避免重复初始化操作,尤其适用于创建成本高的对象(如数据库连接、复杂配置对象)。
1. 核心概念
Prototype(原型接口):声明克隆方法(如 clone())。
Concrete Prototype(具体原型):实现克隆方法,复制自身。
Client(客户端):通过克隆原型对象创建新实例。
2. C++ 代码示例
场景:游戏中的敌人角色复制,每个敌人有位置、血量、技能列表(需深拷贝)。
#include <iostream>
#include <string>
#include <vector>
#include <memory>
// 1. 原型接口
class Enemy {
public:
virtual ~Enemy() = default;
virtual std::unique_ptr<Enemy> clone() const = 0; // 克隆方法
virtual void display() const = 0;
virtual void setPosition(int x, int y) = 0;
};
// 2. 具体原型:弓箭手
class Archer : public Enemy {
private:
int x_, y_;
float health_;
std::vector<std::string> skills_; // 需深拷贝的成员
public:
Archer(int x, int y, float health, const std::vector<std::string>& skills)
: x_(x), y_(y), health_(health), skills_(skills) {}
std::unique_ptr<Enemy> clone() const override {
return std::make_unique<Archer>(*this); // 调用拷贝构造函数
}
void display() const override {
std::cout << "Archer at (" << x_ << ", " << y_ << "), Health: " << health_
<< ", Skills: ";
for (const auto& skill : skills_) {
std::cout << skill << " ";
}
std::cout << std::endl;
}
void setPosition(int x, int y) override {
x_ = x;
y_ = y;
}
// 自定义拷贝构造函数(深拷贝)
Archer(const Archer& other)
: x_(other.x_), y_(other.y_), health_(other.health_), skills_(other.skills_) {}
};
// 3. 客户端使用
int main() {
// 创建原型对象
std::unique_ptr<Enemy> prototype = std::make_unique<Archer>(
10, 20, 100.0f, std::vector<std::string>{"Fire Arrow", "Triple Shot"});
// 克隆新对象并修改位置
auto enemy1 = prototype->clone();
enemy1->setPosition(30, 40);
enemy1->display();
// 输出:Archer at (30, 40), Health: 100, Skills: Fire Arrow Triple Shot
// 再次克隆(完全独立的新对象)
auto enemy2 = prototype->clone();
enemy2->display();
// 输出:Archer at (10, 20), Health: 100, Skills: Fire Arrow Triple Shot
return 0;
}
3. 关键实现细节
深拷贝与浅拷贝:
默认拷贝构造函数执行浅拷贝,若对象包含指针或动态资源,需手动实现深拷贝。
示例中 skills_ 是 std::vector,其拷贝构造函数自动深拷贝,无需额外处理。若成员为原生指针,需手动复制数据。
clone() 方法:
返回 std::unique_ptr<Enemy>,由智能指针管理资源,避免内存泄漏。
调用具体原型的拷贝构造函数生成新对象。
性能优化:
预先创建并缓存原型对象,避免重复初始化高成本资源(如加载模型、读取配置文件)。
4. 面试高频问题
Q1:原型模式与工厂模式的区别?
工厂模式:通过工厂类创建新对象,可能涉及复杂初始化逻辑。
原型模式:通过复制现有对象创建新对象,适合对象创建成本高的场景。
Q2:深拷贝与浅拷贝如何实现?
浅拷贝:仅复制指针地址,新旧对象共享同一块内存(危险!)。
深拷贝:复制指针指向的数据,新旧对象完全独立。
C++实现:自定义拷贝构造函数和赋值运算符。
Q3:原型模式的优缺点?
优点:
避免重复初始化,提升性能。
动态添加或删除产品(通过修改原型配置)。
缺点:
深拷贝实现复杂(尤其含循环引用时)。
需暴露对象内部细节(需公有拷贝构造函数)。
Q4:哪些场景适合原型模式?
对象初始化需要大量资源(如数据库连接、3D模型加载)。
需快速生成相似对象(如游戏中的大量NPC)。
对象状态需动态保存和恢复(如撤销操作的历史记录)。
6. 扩展:原型管理器(Registry)
维护一个原型对象的注册表,客户端按名称获取原型并克隆:
总结
原型模式通过复制而非新建的方式高效创建对象,核心在于:
实现正确的深拷贝(尤其含动态资源时)。
提供统一的克隆接口(clone() 方法)。
结合原型管理器提升灵活性和可维护性。