C++工厂模式详解:从基础到高级应用
1. 工厂模式基础与核心价值工厂模式是面向对象设计中应用最广泛的创建型模式之一其核心在于将对象的实例化过程封装起来使客户端代码与具体类解耦。在C这种强类型语言中工厂模式的价值尤为突出类型安全通过静态类型检查避免运行时类型错误扩展便利新增产品类时无需修改客户端代码逻辑集中将复杂的对象创建条件判断集中管理接口统一所有产品遵循同一抽象接口典型的简单工厂实现如下class Product { public: virtual void operation() 0; virtual ~Product() default; }; class ConcreteProductA : public Product { public: void operation() override { /*...*/ } }; class Factory { public: static std::unique_ptrProduct createProduct(int type) { switch(type) { case 1: return std::make_uniqueConcreteProductA(); // 其他产品类型... default: throw std::invalid_argument(Unknown product type); } } };2. 工厂方法模式进阶实现工厂方法模式通过引入抽象工厂类进一步解耦了具体产品的创建过程。这种模式特别适合以下场景产品类具有层次结构需要运行时动态决定创建哪种产品不同环境下需要创建不同产品一个标准的C工厂方法实现示例// 抽象产品 class Document { public: virtual void open() 0; virtual void save() 0; virtual ~Document() default; }; // 具体产品 class TextDocument : public Document { /*...*/ }; class SpreadsheetDocument : public Document { /*...*/ }; // 抽象工厂 class Application { public: virtual std::unique_ptrDocument createDocument() 0; void newDocument() { auto doc createDocument(); doc-open(); // 添加到文档集合... } }; // 具体工厂 class TextApplication : public Application { public: std::unique_ptrDocument createDocument() override { return std::make_uniqueTextDocument(); } };提示在C中实现工厂方法时建议使用智能指针管理产品对象生命周期避免内存泄漏。3. 抽象工厂模式实战应用抽象工厂模式用于创建相关或依赖对象的家族而不需要明确指定具体类。在游戏开发、UI框架等场景中尤为常见// 抽象产品族 class Button { public: virtual void render() 0; virtual ~Button() default; }; class Checkbox { public: virtual void toggle() 0; virtual ~Checkbox() default; }; // 具体产品族 - Windows风格 class WinButton : public Button { /*...*/ }; class WinCheckbox : public Checkbox { /*...*/ }; // 抽象工厂 class GUIFactory { public: virtual std::unique_ptrButton createButton() 0; virtual std::unique_ptrCheckbox createCheckbox() 0; virtual ~GUIFactory() default; }; // 具体工厂 class WinFactory : public GUIFactory { public: std::unique_ptrButton createButton() override { return std::make_uniqueWinButton(); } std::unique_ptrCheckbox createCheckbox() override { return std::make_uniqueWinCheckbox(); } };4. 模板工厂模式实现技巧C的模板特性可以实现更灵活的工厂模式这种技术常用于库开发中template typename ProductType class GenericFactory { public: template typename... Args static std::unique_ptrProductType create(Args... args) { return std::make_uniqueProductType(std::forwardArgs(args)...); } }; // 使用示例 class CustomProduct { public: CustomProduct(int param1, double param2) { /*...*/ } }; auto product GenericFactoryCustomProduct::create(42, 3.14);这种实现方式的优势在于编译时类型检查完美转发参数无需修改工厂即可支持新产品类型5. 原型模式与工厂的结合原型模式通过克隆现有对象来创建新对象与工厂模式结合可以产生强大的效果class Prototype { public: virtual std::unique_ptrPrototype clone() const 0; virtual ~Prototype() default; }; class ConcretePrototype : public Prototype { int data; public: std::unique_ptrPrototype clone() const override { return std::make_uniqueConcretePrototype(*this); } }; class PrototypeFactory { std::unordered_mapint, std::unique_ptrPrototype prototypes; public: void registerPrototype(int id, std::unique_ptrPrototype proto) { prototypes[id] std::move(proto); } std::unique_ptrPrototype create(int id) const { auto it prototypes.find(id); if (it ! prototypes.end()) { return it-second-clone(); } throw std::invalid_argument(Unknown prototype ID); } };6. 依赖注入框架中的工厂模式现代C依赖注入框架通常内置工厂模式的实现例如class Service { public: virtual void execute() 0; virtual ~Service() default; }; class ServiceFactory { public: virtual std::unique_ptrService create() 0; virtual ~ServiceFactory() default; }; class DIContainer { std::unordered_mapstd::type_index, std::functionstd::unique_ptrvoid() creators; public: template typename T void registerFactory(std::functionstd::unique_ptrT() factory) { creators[typeid(T)] [factory]() - std::unique_ptrvoid { return factory(); }; } template typename T std::unique_ptrT resolve() { auto it creators.find(typeid(T)); if (it ! creators.end()) { return std::unique_ptrT(static_castT*(it-second().release())); } throw std::runtime_error(Service not registered); } };7. 性能优化与线程安全考量在实现工厂模式时性能与线程安全是需要重点考虑的因素对象池技术template typename T class ObjectPool { std::queuestd::unique_ptrT pool; std::mutex mtx; public: template typename... Args void preallocate(size_t count, Args... args) { std::lock_guardstd::mutex lock(mtx); for (size_t i 0; i count; i) { pool.push(std::make_uniqueT(std::forwardArgs(args)...)); } } std::unique_ptrT acquire() { std::lock_guardstd::mutex lock(mtx); if (pool.empty()) return nullptr; auto obj std::move(pool.front()); pool.pop(); return obj; } void release(std::unique_ptrT obj) { std::lock_guardstd::mutex lock(mtx); pool.push(std::move(obj)); } };线程安全工厂class ThreadSafeFactory { static std::mutex instanceMutex; static std::unique_ptrThreadSafeFactory instance; ThreadSafeFactory() default; public: ThreadSafeFactory(const ThreadSafeFactory) delete; ThreadSafeFactory operator(const ThreadSafeFactory) delete; static ThreadSafeFactory getInstance() { std::lock_guardstd::mutex lock(instanceMutex); if (!instance) { instance std::make_uniqueThreadSafeFactory(); } return *instance; } template typename T, typename... Args std::unique_ptrT create(Args... args) { return std::make_uniqueT(std::forwardArgs(args)...); } };8. 现代C特性在工厂模式中的应用C17/20的新特性可以让工厂模式实现更加优雅使用std::variant实现类型安全工厂using ProductVariant std::variant std::unique_ptrConcreteProductA, std::unique_ptrConcreteProductB ; class ModernFactory { public: ProductVariant createProduct(int type) { switch(type) { case 1: return std::make_uniqueConcreteProductA(); case 2: return std::make_uniqueConcreteProductB(); default: throw std::invalid_argument(Unknown type); } } };使用concept约束工厂产品类型template typename T concept ProductConcept requires(T t) { { t.operation() } - std::same_asvoid; }; template ProductConcept T class ConceptFactory { public: std::unique_ptrT create() { return std::make_uniqueT(); } };9. 工厂模式在Qt框架中的实践Qt框架大量使用了工厂模式的思想特别是在对象创建和元对象系统中// Qt风格的工厂方法示例 class QtProduct { public: virtual QString name() const 0; virtual ~QtProduct() default; }; class QtFactory { public: virtual QtProduct* create(QWidget* parent nullptr) 0; virtual ~QtFactory() default; }; // 使用QMap注册工厂 class QtFactoryManager { QMapQString, QtFactory* factories; public: void registerFactory(const QString id, QtFactory* factory) { factories[id] factory; } QtProduct* create(const QString id, QWidget* parent nullptr) { if (factories.contains(id)) { return factories[id]-create(parent); } return nullptr; } };10. 设计模式组合应用案例在实际项目中工厂模式常与其他模式组合使用工厂策略模式class CompressionStrategy { public: virtual void compress(const std::string file) 0; virtual ~CompressionStrategy() default; }; class ZipStrategy : public CompressionStrategy { /*...*/ }; class RarStrategy : public CompressionStrategy { /*...*/ }; class CompressionFactory { public: static std::unique_ptrCompressionStrategy createStrategy(const std::string type) { if (type zip) return std::make_uniqueZipStrategy(); if (type rar) return std::make_uniqueRarStrategy(); throw std::invalid_argument(Unknown compression type); } };工厂装饰器模式class DataStream { public: virtual void write(const std::string data) 0; virtual ~DataStream() default; }; class FileStream : public DataStream { /*...*/ }; class NetworkStream : public DataStream { /*...*/ }; class StreamDecorator : public DataStream { protected: std::unique_ptrDataStream wrapped; public: StreamDecorator(std::unique_ptrDataStream stream) : wrapped(std::move(stream)) {} }; class EncryptedStream : public StreamDecorator { /*...*/ }; class CompressedStream : public StreamDecorator { /*...*/ }; class StreamFactory { public: enum class StreamType { File, Network }; enum class DecoratorType { None, Encrypted, Compressed }; static std::unique_ptrDataStream createStream( StreamType type, DecoratorType decorator DecoratorType::None ) { std::unique_ptrDataStream stream; switch(type) { case StreamType::File: stream std::make_uniqueFileStream(); break; case StreamType::Network: stream std::make_uniqueNetworkStream(); break; } switch(decorator) { case DecoratorType::Encrypted: return std::make_uniqueEncryptedStream(std::move(stream)); case DecoratorType::Compressed: return std::make_uniqueCompressedStream(std::move(stream)); default: return stream; } } };11. 工厂模式在游戏开发中的特殊应用游戏引擎通常需要高效地创建大量游戏对象这时工厂模式的变体显得尤为重要基于组件的对象工厂class GameObject { std::unordered_mapstd::type_index, std::unique_ptrvoid components; public: template typename T, typename... Args T addComponent(Args... args) { auto ptr std::make_uniqueT(std::forwardArgs(args)...); T ref *ptr; components[typeid(T)] std::move(ptr); return ref; } template typename T T* getComponent() { auto it components.find(typeid(T)); if (it ! components.end()) { return static_castT*(it-second.get()); } return nullptr; } }; class PrefabFactory { std::unordered_mapstd::string, std::functionvoid(GameObject) prefabs; public: void registerPrefab(const std::string name, auto configurator) { prefabs[name] std::forwarddecltype(configurator)(configurator); } GameObject create(const std::string name) { GameObject obj; if (prefabs.count(name)) { prefabs[name](obj); } return obj; } };12. 工厂模式的最佳实践与反模式在实际项目中使用工厂模式时需要注意以下实践要点最佳实践优先使用智能指针管理对象生命周期为工厂类定义清晰的接口契约考虑使用依赖注入替代硬编码的工厂对性能敏感的场景使用对象池技术在多线程环境中确保工厂的线程安全常见反模式上帝工厂单个工厂类负责创建过多不同类型的对象过度抽象为简单对象创建引入不必要的工厂层次循环依赖工厂与产品之间存在双向依赖忽略异常安全工厂方法可能抛出异常导致资源泄漏// 良好的工厂接口设计示例 class WellDesignedFactory { public: // 使用std::expected替代异常处理 std::expectedstd::unique_ptrProduct, ErrorCode createProduct(ProductType type) { switch(type) { case ProductType::A: return std::make_uniqueProductA(); case ProductType::B: return std::make_uniqueProductB(); default: return std::unexpected(ErrorCode::InvalidType); } } // 支持批量创建 std::vectorstd::unique_ptrProduct createProducts(std::spanconst ProductType types) { std::vectorstd::unique_ptrProduct products; products.reserve(types.size()); for (auto type : types) { if (auto product createProduct(type)) { products.push_back(std::move(*product)); } } return products; } };

相关新闻

C++模板方法模式:原理、实现与应用场景解析

C++模板方法模式:原理、实现与应用场景解析

1. 模板方法模式的核心概念在C开发中,模板方法模式是一种行为型设计模式,它定义了算法的骨架,将某些步骤延迟到子类中实现。这种模式允许子类在不改变算法结构的情况下重新定义算法的某些特定步骤。我第一次接触这个模式是在开发一个跨平台的…

2026/10/4 8:43:24 阅读更多 →
从非结构化文本到结构化数据:基于规则的信息提取实战

从非结构化文本到结构化数据:基于规则的信息提取实战

1. 这篇文章真正要解决的问题最近,很多技术圈的朋友,尤其是对数据分析、爬虫和自动化脚本感兴趣的朋友,可能会被“体彩10元超英雄奖组数据”这样的标题吸引。乍一看,这似乎是一个纯粹的彩票话题,离我们的技术世界很远。…

2026/10/11 1:06:10 阅读更多 →
AI智能体无服务器化部署实战:基于DigitalOcean Functions的Hermes Agent云端方案

AI智能体无服务器化部署实战:基于DigitalOcean Functions的Hermes Agent云端方案

1. 项目概述:当智能体遇见无服务器最近在折腾AI智能体,特别是像Hermes Agent这类能联网、能执行代码的“数字员工”,发现一个挺普遍的问题:本地部署虽然可控,但资源消耗大,特别是当你想让它7x24小时待命&am…

2026/10/11 2:12:29 阅读更多 →

最新新闻

GeoJSON省市边界数据下载与处理:从结构解析到坐标系统一实战

GeoJSON省市边界数据下载与处理:从结构解析到坐标系统一实战

简介:面向Web前端开发、GIS分析与数据可视化场景的全国省级行政区划GeoJSON数据合集,覆盖34个省级行政区(含省、自治区、直辖市及港澳地区),以省份边界几何信息为核心,可直接用于地图绘制、区域统计与地理数…

2026/10/17 5:25:25 阅读更多 →
高校导师悄悄推荐的AI论文工具实测榜单

高校导师悄悄推荐的AI论文工具实测榜单

如果你这几年在高校读研或者搞科研,大概率见过这样一个名场面:组会上导师板着脸说,论文必须自己写,不许用AI代写;散会后不到两小时,他私聊里发来一个工具链接,附带一句“这个对整理文献有点用&a…

2026/10/17 5:25:25 阅读更多 →
Unity摇钱树捕鱼源码:状态机驱动的休闲游戏开发模板

Unity摇钱树捕鱼源码:状态机驱动的休闲游戏开发模板

简介:这是一份面向C游戏开发初学者与进阶工程师的捕鱼类游戏实战源码,聚焦棋牌捕鱼领域,适用于希望深入理解实时多人游戏架构、算法实现与框架集成的学习者。资源包含客户端与服务器端完整代码,可直接部署于网狐棋牌游戏框架&…

2026/10/17 5:25:25 阅读更多 →
双串锂电池主动均衡设计实战:MP2642+PIC18F56K42方案

双串锂电池主动均衡设计实战:MP2642+PIC18F56K42方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 5:25:25 阅读更多 →
金融级系统建设自检清单:从幂等、风控到高可用与合规落地

金融级系统建设自检清单:从幂等、风控到高可用与合规落地

说实话,接到“financial-services”这个命题,我脑子里第一反应不是那些热得发烫的融资新闻,而是几年前接手一个信贷系统重构时的场景:那会儿业务方甩过来一句话,“系统能跑不算本事,你敢把钱真正放出去再收…

2026/10/17 5:25:25 阅读更多 →
freeCodeCamp信息安全认证实操:HelmetJS+Python渗透测试

freeCodeCamp信息安全认证实操:HelmetJS+Python渗透测试

freeCodeCamp的信息安全认证我在去年集中过一段时间认真刷完了,前后花了大概三周。这套认证和其他课程最大的不同在于,它不是为了让你背几个概念,而是逼着你真正去写代码:一边用HelmetJS给Express应用加固防护,一边用P…

2026/10/17 5:24:25 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →