原型模式通过克隆机制实现对象高效创建,是性能敏感场景的利器。本文结合C++示例详解实现原理、深拷贝陷阱、应用场景,并与工厂模式对比分析。

为何需要原型模式?

当遇到以下场景时,传统构造方法面临挑战:

  1. 创建成本高:对象初始化需访问数据库/读取文件(如游戏角色加载资源)

  2. 状态复杂:对象包含多层嵌套结构(如DOM树节点)

  3. 动态配置:运行时需基于现有对象微调生成新对象

原型模式优势

  • 避开重复初始化开销

  • 免去工厂类继承体系

  • 支持运行时动态对象生成


原型模式核心概念

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象


C++ 深度实现(解决浅拷贝陷阱)

基础实现

#include <iostream>
#include <memory>// 抽象原型
class IPrototype {
public:virtual ~IPrototype() = default;virtual std::unique_ptr<IPrototype> clone() const = 0;virtual void render() const = 0;
};// 具体原型:游戏敌人角色
class Enemy : public IPrototype {
public:Enemy(int hp, int dmg, std::string model) : hp_(hp), damage_(dmg), model_(std::move(model)) {// 模拟高成本资源加载std::cout << "Loading 3D model: " << model_ << "...\n";}std::unique_ptr<IPrototype> clone() const override {return std::make_unique<Enemy>(*this); // 调用拷贝构造}void render() const override {std::cout << "Enemy[HP:" << hp_ << " DMG:" << damage_<< " MODEL:" << model_ << "]\n";}void setHP(int hp) { hp_ = hp; }private:int hp_;int damage_;std::string model_;  // 字符串自动深拷贝
};

含指针成员的深拷贝解决方案

class Weapon {
public:Weapon(std::string name, int dmg) : name_(std::move(name)), base_dmg_(dmg) {}std::unique_ptr<Weapon> clone() const {return std::make_unique<Weapon>(*this);}
private:std::string name_;int base_dmg_;
};class ArmedEnemy : public IPrototype {
public:ArmedEnemy(int hp, std::unique_ptr<Weapon> weapon): hp_(hp), weapon_(std::move(weapon)) {}// 深拷贝关键:递归克隆指针成员std::unique_ptr<IPrototype> clone() const override {auto new_weapon = weapon_->clone();return std::make_unique<ArmedEnemy>(hp_, std::move(new_weapon));}private:int hp_;std::unique_ptr<Weapon> weapon_;  // 需特殊处理
};

具体使用示例

int main() {// 1. 初始化原型对象(高成本操作)auto skeleton_prototype = std::make_unique<Enemy>(100, 15, "skeleton.fbx");// 2. 批量生成敌人(零初始化成本)std::vector<std::unique_ptr<IPrototype>> enemies;for (int i = 0; i < 5; ++i) {auto new_enemy = skeleton_prototype->clone();dynamic_cast<Enemy*>(new_enemy.get())->setHP(80); // 差异化调整enemies.push_back(std::move(new_enemy));}// 3. 验证独立状态enemies[0]->render(); // HP:80skeleton_prototype->render(); // HP:100 (原型不受影响)return 0;
}

应用场景与典型案例

场景案例原型模式作用
游戏开发批量生成同类型敌人/NPC避免重复加载3D模型/纹理
文档编辑复制复杂图表对象保持格式和数据的完整性
机器学习创建相似配置的模型实例快速实验不同超参数
撤销/重做保存对象历史状态通过克隆实现状态快照

优缺点对比分析

 优势

  • 性能提升:规避昂贵初始化操作

  • 动态性:运行时增减产品对象

  • 简化结构:无需工厂类继承体系

陷阱

  • 深拷贝问题:指针成员需递归克隆

  • 循环引用:复杂对象图可能导致拷贝死循环

  • 初始化限制:克隆无法执行构造函数逻辑


与其他创建型模式对比

模式特点适用场景
原型模式通过克隆现有对象创建对象创建成本高或状态复杂
工厂方法子类决定实例化对象类层次结构稳定
抽象工厂创建相关对象家族需要保证产品兼容性
建造者分步构造复杂对象对象包含多个创建步骤

选择原则:当系统需要动态生成对象或避免初始化开销时,优先选择原型模式


最佳实践

  1. 实现Clone接口:明确标识可克隆对象

  2. 深拷贝防御:对指针/引用类型实现递归克隆

  3. 原型管理器:使用注册表管理常用原型

    class PrototypeRegistry {std::unordered_map<std::string, std::unique_ptr<IPrototype>> prototypes_;
    public:void add(const std::string& key, std::unique_ptr<IPrototype> proto) {prototypes_[key] = std::move(proto);}std::unique_ptr<IPrototype> clone(const std::string& key) {return prototypes_.at(key)->clone();}
    };

“原型模式不是从零开始构造对象,而是通过克隆现有实例来高效创建新对象,它是面向对象设计中复制与复用对象实例的巧妙捷径。“ - 设计模式实践者

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/86602.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/86602.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/86602.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go 语言中的单元测试

1、如何编写单元测试 在任何生产级别的项目开发中&#xff0c;单元测试都扮演着至关重要的角色。尽管许多初创项目在早期可能忽略了它&#xff0c;但随着项目逐渐成熟并成为核心业务&#xff0c;为其编写健壮的单元测试是保障代码质量和项目稳定性的必然选择。本文将带您快速掌…

8. 接口专业测试报告生成pytest-html

pytest-html 终极指南&#xff1a;打造专业级接口测试报告 在接口自动化测试中&#xff0c;清晰的测试报告是质量保障的关键。本文将深入解析如何通过pytest-html插件生成专业级测试报告。 一、核心安装与基础使用 快速安装&#xff08;国内镜像&#xff09; pip install -i …

Day45 Tensorboard使用介绍

目录 一、tensorboard的发展历史和原理及基本操作 1.1 发展历史 1.2 tensorboard的原理 1.3 日志目录自动管理 1.4 记录标量数据&#xff08;Scalar&#xff09; 1.5 可视化模型结构&#xff08;Graph&#xff09; 1.6 可视化图像&#xff08;Image&#xff09; 1.7 记…

用AI给AR加“智慧”:揭秘增强现实智能互动的优化秘密

用AI给AR加“智慧”:揭秘增强现实智能互动的优化秘密 引子:增强现实,到底还能怎么更聪明? 还记得当年Pokmon GO火爆全球的场景吗?玩家们手机对准街头,虚拟小精灵活灵活现地跳出来,那就是增强现实(AR)最经典的应用之一。随着硬件发展和算法进步,AR正逐步从“炫酷玩具…

1 Studying《Computer Vision: Algorithms and Applications 2nd Edition》1-5

目录 Chapter 1 Introduction 1.1 什么是计算机视觉&#xff1f; 1.2 简史 1.3 书籍概述 1.4 样本教学大纲 1.5 符号说明 1.6 其他阅读材料 Chapter 2 Image formation 2.1 几何基本元素和变换 2.2 光度图像形成 2.3 数码相机 2.4 其他阅读材料 2.5 练习 Chapter…

Augment插件macOS

macOS苹果电脑vscode-augment免费额度续杯跑满 前言 在AI辅助编程日益普及的今天&#xff0c;Augment作为VS Code中的智能代码助手&#xff0c;为开发者提供了强大的代码生成和优化功能。然而&#xff0c;免费版本每月300次的使用限制往往让重度用户感到困扰。本文将详细介绍如…

OpenCV CUDA模块设备层-----创建一个“常量指针访问器” 的工具函数constantPtr()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 CUDA 设备端模拟一个“指向常量值”的虚拟指针访问器&#xff0c;使得你可以像访问数组一样访问一个固定值。 这在某些核函数中非常有用&…

Python:操作 Excel 删除工作簿

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…

Python类型注解(Type Hints)的工程实践指南

一、类型注解的核心价值 代码可读性&#xff1a;明确函数输入输出类型 静态检查&#xff1a;配合mypy提前发现类型错误 IDE支持&#xff1a;提升代码补全和重构能力 文档替代&#xff1a;类型即文档的现代编程理念 二、基础语法规范 def greet(name: str, times: int 1)…

Hadoop RPC 分层设计的哲学:高内聚、低耦合的最佳实践

Hadoop RPC Hadoop RPC主要分为四个部分&#xff0c;分别是序列化层、函数调用层、网络传输层和服务器端处理框架&#xff0c;实现机制为&#xff1a; 序列化层&#xff1a;主要作用是将结构化对象转为字节流以便于通过网络进行传输或写入持久存储。函数调用层&#xff1a;主…

MybatisPlus-01.MybatisPlus介绍

一.MybatisPlus介绍 MybatisPlus是对Mybatis的增强和升级&#xff0c;但需要注意的是&#xff0c;MybatisPlus并不是取代Mybatis的&#xff0c;而是要做Mybatis最好的合作伙伴。左边蓝色的小鸟就是MybatisPlus的标志。 在MybatisPlus官方页面上介绍了其特点&#xff0c;首先&am…

人大金仓数据库jdbc连接jar包kingbase8-8.6.0.jar驱动包最新版下载(不需要积分)

看了网上的很多&#xff0c;都是需要下载积分的 分享一下直接访问人大金仓官网&#xff0c;下载对应的数据库jdbc连接jar包kingbase8-8.6.0.jar驱动包&#xff1a; 点击 服务与支持&#xff0c;然后选择 下载中心 选择对应的产品和版本&#xff0c;最后选择软件版本 看到有…

cf 禁止http/1.0和http/1.1的访问 是否会更安全?

使用 Cloudflare&#xff08;CF&#xff09;禁止 HTTP/1.0 和 HTTP/1.1 的访问&#xff0c;强制客户端使用 HTTP/2 或更高版本&#xff08;如 HTTP/3&#xff09;&#xff0c;在某些情况下可以提升网站安全性&#xff0c;但也存在权衡和限制。以下是详细分析&#xff0c;帮你判…

【Docker基础】Docker容器管理:docker pause详解

目录 1 Docker容器管理概述 2 docker pause命令详解 2.1 命令基本语法 2.2 命令功能解析 2.3 暂停与停止的区别 3 docker pause的工作流程 3.1 工作流程概述 3.2 工作流程详解 4 docker pause的使用场景 4.1 资源临时调整 4.2 调试与检查 4.3 服务维护 4.4 数据备…

Springboot ResponseBodyAdvice 的小妙用

最近公司接触到了政府项目&#xff0c;在开发完成后&#xff0c;需要对代码做安全扫描&#xff0c;对系统做安全测试&#xff0c;在安全测试中有一项不合格&#xff0c;就是接口返回错误是&#xff0c;错误不是浏览器级别的&#xff0c;什么意思呢&#xff0c;一般我们都会封装…

Re:从零开始的文件结构(融合线性表来理解 考研向)

文件管理 & 线性表 文件管理文件的结构无结构文件 有结构文件&#xff08;重点&#xff09;定长与不定长记录顺序文件&#xff08;类线性表&#xff09;它的逻辑结构它的物理结构&#xff08;存储结构&#xff09;小结 索引顺序文件与多级索引顺序文件形象化理解&#xff0…

并发基础7(守护线程)

目录 1&#xff1a;什么守护线程 2&#xff1a;守护线程使用 3&#xff1a;守护线程案例 1&#xff1a;什么守护线程 守护线程是Java中的一种特殊的线程类型&#xff0c;它为其他线程&#xff08;非守护线程&#xff09;提供后台支持服务。 在Java多线程编程中&#xff0c…

蜣螂算法+四模型对比!DBO-CNN-BiLSTM-Attention系列四模型多变量时序预测

蜣螂算法四模型对比&#xff01;DBO-CNN-BiLSTM-Attention系列四模型多变量时序预测&#xff08;Matlab完整源码和数据&#xff09; 目录 蜣螂算法四模型对比&#xff01;DBO-CNN-BiLSTM-Attention系列四模型多变量时序预测&#xff08;Matlab完整源码和数据&#xff09;效果一…

服务器的维护技术都有哪些?

服务器的稳定性与可靠性是十分重要的&#xff0c;当服务器出现故障或损坏时&#xff0c;会影响业务的正常运行&#xff0c;还会导致数据丢失给企业带来巨大的经济损失&#xff0c;所以大多数的企业通常掌握着有效的服务器维护技术&#xff0c;不仅能够提高服务器的稳定性&#…

Go 语言并发编程

Go 语言的并发模型是其区别于其他编程语言的重要特性之一&#xff0c;它以简洁高效的方式解决了现代编程中多核处理器利用和高并发场景的需求。 一、并发与并行&#xff1a;概念与区别 在理解 Go 的并发模型之前&#xff0c;需要明确并发与并行的差异&#xff1a; 并发&…