当前位置: 首页 > article >正文

新谈设计模式 Chapter 05 — 原型模式 Prototype

Chapter 05 — 原型模式 Prototype灵魂速记复印机——照着原件复制一份省得从头再造。秒懂类比你有一份精心排版的简历模板。每次投不同公司你不是从头写一份新的而是复印一份改几个字。原型模式就是这个复印动作——通过克隆已有对象来创建新对象。问题引入// 灾难现场你拿到一个对象想复制一份voidduplicate(Shape*shape){// 问题1shape 是 CircleRectangleTriangle你不知道// 问题2就算知道有些属性是 private 的你访问不了// 问题3你依赖了具体类型违反了面向接口编程if(auto*cdynamic_castCircle*(shape)){auto*copynewCircle(*c);// 要写一堆 dynamic_cast}elseif(auto*rdynamic_castRectangle*(shape)){auto*copynewRectangle(*r);}// 每加一种形状这里就要加一段……}你需要的是不管什么类型调一个方法就能得到一个一模一样的副本。模式结构┌───────────────┐ │ Prototype │ ├───────────────┤ │ clone() │ ← 核心自我复制的能力 └───────┬───────┘ │ 实现 ┌────┴─────┐ │ │ ┌──┴──┐ ┌───┴────┐ │CircleP│ │RectangleP│ │clone()│ │ clone() │ └──────┘ └─────────┘精髓每个对象自己知道怎么复制自己因为自己能访问自己的 private 成员。C 实现#includeiostream#includememory#includestring#includeunordered_map// 原型接口 classShape{public:virtual~Shape()default;virtualstd::unique_ptrShapeclone()const0;// 核心方法virtualvoiddraw()const0;voidsetColor(conststd::stringcolor){color_color;}std::stringcolor()const{returncolor_;}protected:std::string color_black;};// 具体原型 classCircle:publicShape{public:Circle(doubleradius):radius_(radius){}// 拷贝构造 clone —— 自己复制自己Circle(constCircleother)default;std::unique_ptrShapeclone()constoverride{returnstd::make_uniqueCircle(*this);// 调用拷贝构造}voiddraw()constoverride{std::cout○ Circle(rradius_, colorcolor_)\n;}private:doubleradius_;};classRectangle:publicShape{public:Rectangle(doublew,doubleh):width_(w),height_(h){}Rectangle(constRectangleother)default;std::unique_ptrShapeclone()constoverride{returnstd::make_uniqueRectangle(*this);}voiddraw()constoverride{std::cout□ Rectangle(width_×height_, colorcolor_)\n;}private:doublewidth_,height_;};// 原型注册表可选方便管理模板 classShapeRegistry{public:voidaddPrototype(conststd::stringname,std::unique_ptrShapeproto){prototypes_[name]std::move(proto);}std::unique_ptrShapecreate(conststd::stringname)const{autoitprototypes_.find(name);if(it!prototypes_.end()){returnit-second-clone();// 从模板克隆}returnnullptr;}private:std::unordered_mapstd::string,std::unique_ptrShapeprototypes_;};intmain(){// 基本用法克隆对象 autooriginalstd::make_uniqueCircle(5.0);original-setColor(red);autocopyoriginal-clone();// 复制不需要知道具体类型std::cout原件;original-draw();std::cout副本;copy-draw();// 修改副本不影响原件copy-setColor(blue);std::cout改色后;copy-draw();std::cout原件;original-draw();// 还是 redstd::cout\n 使用注册表 \n;// 注册表用法预存模板 ShapeRegistry registry;autocircleTemplatestd::make_uniqueCircle(10.0);circleTemplate-setColor(green);registry.addPrototype(big-green-circle,std::move(circleTemplate));autorectTemplatestd::make_uniqueRectangle(100,50);rectTemplate-setColor(yellow);registry.addPrototype(banner,std::move(rectTemplate));// 从模板快速创建autos1registry.create(big-green-circle);autos2registry.create(banner);s1-draw();s2-draw();}输出原件○ Circle(r5, colorred) 副本○ Circle(r5, colorred) 改色后○ Circle(r5, colorblue) 原件○ Circle(r5, colorred) 使用注册表 ○ Circle(r10, colorgreen) □ Rectangle(100×50, coloryellow)深拷贝 vs 浅拷贝这是原型模式最容易翻车的地方。C 的默认拷贝构造是逐成员拷贝memberwise copy。对于值类型int、std::string这没问题。但如果成员是指针classDocument{std::string title_;std::vectorPage*pages_;// 裸指针// 默认拷贝构造 → 浅拷贝// 新 Document 的 pages_ 和原来的指向同一批 Page 对象// 改一个另一个也变了。析构时还会 double-free。};解决方案如果成员涉及堆上资源必须手写拷贝构造做深拷贝。用智能指针可以让意图更明确classDocument{std::string title_;std::vectorstd::unique_ptrPagepages_;// 手写拷贝构造 —— 深拷贝每一个 PageDocument(constDocumentother):title_(other.title_){pages_.reserve(other.pages_.size());for(constautopage:other.pages_){pages_.push_back(page-clone());// 递归克隆}}// 注意声明了拷贝构造后编译器不再隐式生成移动构造。// 如果需要移动语义要显式写 defaultDocument(Document)default;Documentoperator(Document)default;// 拷贝赋值也得跟着写Rule of FiveDocumentoperator(constDocumentother){if(this!other){title_other.title_;pages_.clear();pages_.reserve(other.pages_.size());for(constautopage:other.pages_){pages_.push_back(page-clone());}}return*this;}};这里体现了 C 的Rule of Five如果你手写了析构函数、拷贝构造、拷贝赋值、移动构造、移动赋值中的任何一个通常五个都需要考虑。原型模式和这条规则天然有关联——一旦你要clone()就必须认真对待拷贝语义。什么时候用✅ 适合❌ 别用创建成本高需要读数据库/文件/网络创建成本低new 一下就行需要克隆运行时才知道类型的对象编译期就知道类型对象有很多配置想保存模板对象很简单没有复杂状态想避免大量子类避免工厂爆炸对象没有拷贝语义防混淆Prototype vs Factory MethodPrototypeFactory Method创建方式复制已有对象从头 new 新对象需要子类不需要工厂子类需要为每种产品写工厂子类灵活度运行时配置模板编译期确定类型类比复印工厂流水线一句话分清Prototype 是照着抄Factory 是从头造。Prototype vs 拷贝构造Prototype (clone)直接拷贝构造多态✅ 不需要知道具体类型❌ 必须知道具体类型返回类型基类指针/unique_ptr具体类型适用场景通过接口操作时知道具体类时clone()本质是对拷贝构造的多态封装。现代 C 小贴士C 有天然的原型支持——拷贝构造函数。但问题是拷贝构造不支持多态所以需要clone()来包装。如果你用 C20 的 Concepts可以约束 clone 接口templatetypenameTconceptCloneablerequires(constTt){{t.clone()}-std::convertible_tostd::unique_ptrShape;};// 说明这里约束的是 convertible_tounique_ptrShape 而非 unique_ptrT。// 原因C 的 unique_ptr 不支持协变返回类型covariant return types——// clone() 在类层次结构中只能返回 unique_ptrShape基类无法返回 unique_ptrCircle派生类。// 若写成 convertible_tounique_ptrTCloneableCircle 会失败// unique_ptrShape 无法隐式转换为 unique_ptrCircle。// 如需编译期强类型克隆可结合 CRTP 实现超出本章范围了解即可。templateCloneable Tstd::unique_ptrShapeduplicateAndModify(constToriginal){autocopyoriginal.clone();// 返回 unique_ptrShape// ... 修改 copyreturncopy;}五大创建型模式总结学完了创建型五兄弟来个总结模式一句话核心手段Singleton只要一个静态实例 私有构造Factory Method子类决定造什么继承 重写Abstract Factory造一整套配套的工厂接口 产品族Builder一步步配出来链式调用 分步构建Prototype照着现有的抄clone() 拷贝构造

相关文章:

新谈设计模式 Chapter 05 — 原型模式 Prototype

Chapter 05 — 原型模式 Prototype灵魂速记:复印机——照着原件复制一份,省得从头再造。秒懂类比 你有一份精心排版的简历模板。每次投不同公司,你不是从头写一份新的,而是复印一份,改几个字。 原型模式就是这个"…...

Qwen3.5-4B模型10分钟快速部署体验:开箱即用的推理服务

Qwen3.5-4B模型10分钟快速部署体验:开箱即用的推理服务 1. 惊艳的开箱即用体验 第一次在星图GPU平台上部署Qwen3.5-4B模型时,我有点不敢相信整个过程如此简单。从选择镜像到完成部署,再到开始第一次对话,全程只用了不到10分钟。…...

Apache DolphinScheduler 三月大动作,你知道几个?

嘿!2026 年 3 月 月报来啦!Apache DolphinScheduler 社区超给力~ 13 位小伙伴踊跃贡献代码,发布了 3.4.1 昕版本,调度增强、任务插件升级,还优化 API 与 UI,修复超 15 个 Bug。 与此同时,基础设…...

【2026年最新600套毕设项目分享】springboot智慧医疗管理系统(14315)

有需要的同学,源代码和配套文档领取,加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码(前后端源代码SQL脚本)配套文档(LWPPT开题报告/任务书)远程调试控屏包运行一键启动项目&…...

突破ComfyUI下载瓶颈:3大秘诀让开源工具效率提升300%实战指南

突破ComfyUI下载瓶颈:3大秘诀让开源工具效率提升300%实战指南 【免费下载链接】ComfyUI-Manager ComfyUI-Manager is an extension designed to enhance the usability of ComfyUI. It offers management functions to install, remove, disable, and enable variou…...

KOOK艺术馆入门必看:Streamlit缓存机制与大模型加载优化技巧

KOOK艺术馆入门必看:Streamlit缓存机制与大模型加载优化技巧 想象一下,你刚刚部署了璀璨星河艺术馆,这个界面美得像卢浮宫画廊的AI绘画工具。你兴奋地输入了第一个创意描述,点击生成按钮,然后...开始了漫长的等待。界…...

一键搞定完整网页截图:Chrome扩展终极解决方案

一键搞定完整网页截图:Chrome扩展终极解决方案 【免费下载链接】full-page-screen-capture-chrome-extension One-click full page screen captures in Google Chrome 项目地址: https://gitcode.com/gh_mirrors/fu/full-page-screen-capture-chrome-extension …...

cursor ctrl+方法跳转

扩展中安装了python就解决了,...

深朴智能与生数科技达成深度战略合作,共筑物理世界的通用智能

4月2日,通用具身智能机器人企业北京深朴智能科技有限公司(以下简称“深朴智能”)与通用世界模型公司北京生数科技有限公司(以下简称“生数科技”)宣布达成深度战略合作。双方将围绕“通用具身智能大脑”这一核心方向展…...

nVisual设备板卡关联

在线模型库导入:ODF-12x2 这个型号的设备打开模型库点左侧模型搜索需要添加板卡设备型号,点击建模双击板卡搜索板卡名称点击绿色按钮添加添加完成点应用到实例...

D3KeyHelper深度评测:5大实战技巧提升暗黑破坏神3操作效率

D3KeyHelper深度评测:5大实战技巧提升暗黑破坏神3操作效率 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 还在为暗黑破坏神3中复杂的技能…...

QKeyMapper终极指南:如何在不重启Windows的情况下彻底改变你的按键习惯

QKeyMapper终极指南:如何在不重启Windows的情况下彻底改变你的按键习惯 【免费下载链接】QKeyMapper [按键映射工具] QKeyMapper,Qt开发Win10&Win11可用,不修改注册表、不需重新启动系统,可立即生效和停止。支持游戏手柄映射到…...

你的微信记忆银行:三分钟学会永久保存珍贵聊天记录

你的微信记忆银行:三分钟学会永久保存珍贵聊天记录 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMs…...

化疗对女性的杀伤力

化疗人群普遍存在体质虚弱、免疫力下降、食欲差、体力透支、肠胃不适等问题,白之品海参凭借其天然温和的营养特点,能在多个方面提供针对性支持:温和滋补,不刺激肠胃海参性平温和,不燥热、不寒凉,对化疗后敏…...

【AI】AI安全工具:常用AI安全检测工具的使用教程

AI安全工具:常用AI安全检测工具的使用教程📝 本章学习目标:本章介绍实用工具,帮助读者掌握AI安全合规治理的工具使用。通过本章学习,你将全面掌握"AI安全工具:常用AI安全检测工具的使用教程"这一…...

Linunx常用命令

一. 通用1.1系统单元启动# 创建系统用户,不允许登录,不创建 home 目录 sudo useradd -r -s /sbin/nologin xxl-job#将 /data/middleware/xxl-job 目录的归属权改为 xxl-job 用户: sudo chown -R xxl-job:xxl-job /data/middleware/xxl-job#检…...

MRiLab:基于多物理场耦合的磁共振成像全流程仿真平台

MRiLab:基于多物理场耦合的磁共振成像全流程仿真平台 【免费下载链接】MRiLab A Numerical Magnetic Resonance Imaging (MRI) Simulation Platform 项目地址: https://gitcode.com/gh_mirrors/mr/MRiLab MRiLab作为开源数值磁共振成像仿真平台,通…...

高新申报通关指南:资深工程师手把手教你准备全套材料(附清单)

高新技术企业认定不仅是企业税负减免的“金钥匙”,更是研发实力与技术体系的重要证明。很多技术人员觉得这只是财务或行政的事,但实则技术材料的质量直接决定了申报成败。 一、 基础资质与人员结构 这部分是申报的“地基”,务必确保真实且符合…...

为什么要学习大模型?从新手到专家:AI大模型学习与实践完全指南

一、初聊大模型 1、什么是大模型? 大模型,通常指的是在人工智能领域中的大型预训练模型。你可以把它们想象成非常聪明的大脑,这些大脑通过阅读大量的文本、图片、声音等信息,学习到了世界的知识。这些大脑(模型&…...

洛谷P1678烦恼的高考志愿题解

一、题目理解输入:第一行、m所学校,n位学生第二行、m个预计录取分数第三行、n个学生估分成绩输出:最小不满意度之和二、解题思路其实这题就是简单的二分,对于我这种菜鸟来说,咱就用最简单最好理解的方式来写。1、首先观…...

OpenMS终极指南:如何快速掌握专业质谱数据分析的完整方案

OpenMS终极指南:如何快速掌握专业质谱数据分析的完整方案 【免费下载链接】OpenMS The codebase of the OpenMS project 项目地址: https://gitcode.com/gh_mirrors/op/OpenMS 蛋白质组学、代谢组学、质谱数据分析、OpenMS开源平台、生物信息学工具 在生命科…...

文件自动同步软件哪个好?企业级高效安全同步方案测评

文件自动同步软件对于许多中大型企业来说,是不可或缺的底层基础设施。不管是内部的多个服务器系统之间,跨部门团队之间,还是和外部的供应链伙伴、总部分支机构之间,都需要依赖文件自动同步软件来实现安全、自动化的文件传输与数据…...

3分钟快速配置:Boss-Key职场隐私保护终极指南

3分钟快速配置:Boss-Key职场隐私保护终极指南 【免费下载链接】Boss-Key 老板来了?快用Boss-Key老板键一键隐藏静音当前窗口!上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在数字化办公时代,隐…...

新手零压力入门:基于快马平台的ubuntu22.04图文安装实战指南

最近在帮几个朋友入门Linux系统时,发现Ubuntu安装这个看似简单的第一步,对新手来说却充满各种"坑"。从制作启动盘到分区设置,每个环节都可能让初学者手足无措。好在发现了InsCode(快马)平台,它能将复杂的安装过程转化为…...

Comsol 双层结构曲界面声场仿真探索

comsol 双层结构曲界面声场仿真 聚焦探头(焦距60mm,晶片直径14mm)辐射声场在双层介质(水钢)中声压分布,钢为凸界面,曲率半径50mm 当第二层介质声速大于第一层介质声速时,凸界面使声场…...

小鹅通重磅升级|AI Agent 能力全面护航,私域智能经营新范式

*文中配图及虚拟数据仅作效果展示 随着人工智能越来越贴近经营场景,小鹅通紧扣各位商家的实际需求,在原有产品基础上,以AI Agent为核心,完成了新一轮产品升级——在原有功能基础上,引入场景skills,并通过sk…...

修改 WindTerm 快捷键配置为Ctrl+V / Ctrl+C

为了让 复制 / 粘贴 的快捷键更符合 Windows 的使用习惯,可以按下面的方法修改 WindTerm 的配置文件。 一、找到配置文件 先进入 WindTerm 的安装目录,然后依次打开: global 文件夹 在该文件夹中找到以下配置文件之一: wind.keyma…...

4步实现Axure软件本地化:专业设计师的效率提升指南

4步实现Axure软件本地化:专业设计师的效率提升指南 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 当你面对全英文界…...

AI辅助开发:让快马AI成为你的编程搭档,智能生成健壮的msi安装管理类库

AI辅助开发:让快马AI成为你的编程搭档,智能生成健壮的msi安装管理类库 最近在开发一个需要处理软件安装包管理的项目,其中涉及到大量.msi文件的安装、卸载和状态检查。这类操作虽然标准化程度高,但实际开发中会遇到各种边界情况和…...

2种开源工具解决方案解决Beyond Compare 5授权失效问题

2种开源工具解决方案解决Beyond Compare 5授权失效问题 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen Beyond Compare 5作为一款专业的文件比较与同步工具,在软件开发和数据管理领域…...