C++设计模式:从生活场景到代码实战

发布时间:2026/7/28 9:17:28

C++设计模式:从生活场景到代码实战
C设计模式从生活场景到代码实战设计模式是软件开发中解决常见问题的经典方案它们源自于建筑学中的模式概念被引入到软件工程领域后成为了程序员们应对复杂系统设计的利器。对于C开发者而言掌握设计模式不仅能够提升代码的可维护性和复用性还能让我们在团队协作中拥有更统一的语言。然而许多初学者面对23种GoF设计模式时常常感到抽象难懂。本文将从生活场景出发用C代码实战演示几种常用设计模式帮助你轻松入门。一、单例模式全球唯一的“打印机”想象一下在一个办公室里只有一台共享打印机。无论哪个部门的员工需要打印文件都必须使用这台唯一的设备。如果每个人都在自己的电脑上安装一台打印机不仅成本高昂还会造成资源冲突。单例模式正是为了解决这种“全局唯一实例”的问题而生的。在C中实现线程安全的单例模式有多种方式其中C11标准后的局部静态变量方法是推荐方案之一class Printer { public: static Printer getInstance() { static Printer instance; return instance; } void print(const std::string doc) { std::cout 打印 doc std::endl; } private: Printer() default; ~Printer() default; Printer(const Printer) delete; Printer operator(const Printer) delete; };这段代码中getInstance()函数返回一个静态局部变量它只会在第一次调用时初始化一次。构造函数被声明为私有杜绝了外部创建新实例的可能。拷贝构造函数和赋值运算符也被删除确保单例的唯一性。在实际开发中这种模式常用于日志系统、配置管理器等场景。二、工厂模式点餐系统的“厨房”去餐厅吃饭时你只需要告诉服务员想吃什么厨房就会根据你的订单制作对应的菜品。你不必关心厨房里有多少厨师、用了什么食材、烹饪过程如何。工厂模式就像这个厨房它将对象的创建过程封装起来客户端只需通过工厂接口获取所需对象无需知道具体实现细节。考虑一个简单的披萨点餐系统class Pizza { public: virtual void prepare() 0; virtual ~Pizza() default; }; class CheesePizza : public Pizza { public: void prepare() override { std::cout 准备芝士披萨 std::endl; } }; class PepperoniPizza : public Pizza { public: void prepare() override { std::cout 准备意大利辣香肠披萨 std::endl; } }; class PizzaFactory { public: static std::unique_ptrPizza createPizza(const std::string type) { if (type cheese) { return std::make_uniqueCheesePizza(); } else if (type pepperoni) { return std::make_uniquePepperoniPizza(); } return nullptr; } };客户端只需调用PizzaFactory::createPizza(cheese)就能获得一个芝士披萨对象而不需要知道CheesePizza类的存在。当系统需要增加新的披萨种类时只需添加新的子类并修改工厂方法即可符合开闭原则。三、观察者模式天气预报的“订阅机制”你是否订阅过天气预报推送当气象台发布新的天气信息时所有订阅了该服务的用户都会收到通知。观察者模式就是这种一对多的依赖关系当一个对象主题的状态发生变化时所有依赖于它的对象观察者都会得到通知并自动更新。在C中实现观察者模式通常会使用std::function和std::vector来管理回调函数class WeatherStation { private: std::vectorstd::functionvoid(int) observers; int temperature; public: void addObserver(std::functionvoid(int) obs) { observers.push_back(obs); } void setTemperature(int temp) { temperature temp; notify(); } void notify() { for (auto obs : observers) { obs(temperature); } } }; // 使用示例 WeatherStation station; station.addObserver([](int temp) { std::cout 用户A收到温度 temp °C std::endl; }); station.addObserver([](int temp) { std::cout 用户B收到温度 temp °C std::endl; }); station.setTemperature(25); // 两个用户都会收到通知这种模式在图形界面编程、事件驱动系统中应用广泛。比如一个按钮被点击时所有注册了点击事件的监听器都会被触发。四、策略模式旅行出行的“交通方式”计划一次旅行时你可以选择开车、坐火车、乘飞机或骑自行车每种方式都有不同的路线规划、时间成本和费用。策略模式允许你在运行时选择算法或行为而不是在编译时固定下来。这就像旅行时根据实际情况灵活切换交通方式。假设我们有一个排序系统需要根据数据量大小选择不同的排序算法class SortStrategy { public: virtual void sort(std::vectorint data) 0; virtual ~SortStrategy() default; }; class QuickSort : public SortStrategy { public: void sort(std::vectorint data) override { std::cout 使用快速排序 std::endl; // 快速排序实现... } }; class BubbleSort : public SortStrategy { public: void sort(std::vectorint data) override { std::cout 使用冒泡排序 std::endl; // 冒泡排序实现... } }; class Sorter { private: std::unique_ptrSortStrategy strategy; public: void setStrategy(std::unique_ptrSortStrategy s) { strategy std::move(s); } void executeSort(std::vectorint data) { if (strategy) { strategy-sort(data); } } };客户端可以根据数据特征动态选择策略数据量小时用冒泡排序数据量大时切换到快速排序。这种模式让算法独立于使用它的客户端便于扩展和测试。五、总结与实践建议设计模式不是银弹它们是在特定上下文中解决特定问题的工具。初学者容易陷入“为了用模式而用模式”的误区反而使代码变得复杂。我的建议是第一从实际需求出发。当你在代码中发现重复的创建逻辑、难以维护的if-else分支、或者需要解耦的依赖关系时才考虑引入设计模式。第二不要一次性学习所有模式。先掌握单例、工厂、观察者、策略这四种最常用的模式通过实际项目练习巩固再逐步学习其他模式。第三阅读优秀开源代码。像Qt、Boost、LLVM等C项目都大量使用了设计模式通过分析它们的代码可以加深理解。设计模式的学习是一个循序渐进的过程就像学习一门新语言一样需要不断的实践和反思。希望本文通过生活场景的类比和C代码的实战能为你打开设计模式的大门让你在日后的开发中写出更优雅、更健壮的代码。

相关新闻

C++代码重构:从混乱到优雅的实战指南

C++代码重构:从混乱到优雅的实战指南

2026/7/28 9:17:28

C代码重构:从混乱到优雅的实战指南——从意大利面条式代码到整洁架构的蜕变之路每个C开发者都曾面对过这样的场景:一个长达800行的函数,嵌套了六层if-else,全局变量像野草般散布在文件的各个角落,类之间的依赖关系堪比…

JetBrains IDE试用期重置终极指南:一键免费续期30天

JetBrains IDE试用期重置终极指南:一键免费续期30天

2026/7/28 9:17:28

JetBrains IDE试用期重置终极指南:一键免费续期30天 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 你是否在为JetBrains IDE试用期到期而烦恼?每次30天评估期结束后,那些强大的…

C++多线程安全编程

C++多线程安全编程

2026/7/28 9:17:28

多线程访问共享数据时那些让人头疼的崩溃和死锁线上服务跑着跑着就core dump,debug版本却怎么也复现不了。这个问题在C多线程编程里太常见了,尤其是涉及全局变量或单例对象时。你盯着日志里最后一条正常记录,再往下就是段错误,连堆…

AI搜索的答案生成机制及对内容运营的影响

AI搜索的答案生成机制及对内容运营的影响

2026/7/28 10:17:31

AI搜索的答案生成机制及对内容运营的影响 随着生成式AI技术的成熟,搜索引擎正在从“链接列表”向“直接答案”演进。用户不再需要在十条蓝色链接中逐一筛选,而是由AI模型实时整合多源信息,生成一段结构化的自然语言回答。这一变化不仅改变了…

【板子】LCA 树链剖分

【板子】LCA 树链剖分

2026/7/28 10:17:31

这是另一种非常经典的求解最近公共祖先(LCA)的方法:树链剖分(Heavy-Light Decomposition)。与Tarjan 算法(离线算法)不同,树链剖分是一种在线算法。1. 核心概念:什么是“…

【板子】LCA Tarjan

【板子】LCA Tarjan

2026/7/28 10:17:31

这是一份基于 Tarjan(塔扬)算法的最近公共祖先(LCA)模板及详细讲解。该算法利用离线处理和并查集的思想,是目前求解 LCA 问题最高效的算法之一(时间复杂度 O(NQ),其中 N 为节点数,Q …

芯粒技术:半导体行业的成本与性能革命

芯粒技术:半导体行业的成本与性能革命

2026/7/28 10:17:31

1. 芯粒技术:半导体行业的范式革命当我在汽车电子实验室第一次拆解2024款智能汽车的域控制器时,一个指甲盖大小的模块引起了我的注意——这个集成了AI加速、传感器融合和通信功能的复杂系统,竟是由多个独立的小芯片像乐高积木一样拼接而成。这…

基于CH32x033的Arduino USB键盘开发:从环境搭建到HID设备实现

基于CH32x033的Arduino USB键盘开发:从环境搭建到HID设备实现

2026/7/28 10:17:31

1. 项目缘起:当Arduino遇上国产MCU的USB键盘梦最近在捣鼓一个桌面小工具,核心需求是想用一块小巧的开发板,通过USB接口模拟成一个键盘,自动执行一些按键序列,比如快速输入一串复杂的密码、或者一键打开某个软件组合。这…

智能回复系统构建指南:从NLP原理到工程部署实践

智能回复系统构建指南:从NLP原理到工程部署实践

2026/7/28 10:07:30

最近在社交媒体技术圈看到一个有趣的现象:Fable这个AI研究团队用8万条推文回应了用户的质疑。这背后其实反映了当前AI内容生成领域的一个重要趋势——大规模数据训练与用户反馈的闭环优化。本文将深入分析这一事件的技术背景,并手把手教你如何构建类似的…

[具身智能-649]:个人电脑搭建 RTSP 服务完整方案(Windows / Ubuntu 双平台,适配 RDK X5 rtsp2display 调试)

[具身智能-649]:个人电脑搭建 RTSP 服务完整方案(Windows / Ubuntu 双平台,适配 RDK X5 rtsp2display 调试)

2026/7/27 8:45:59

目标:电脑作为RTSP 服务端,循环推送 H264/H265 视频流; RDK X5 通过 rtsp2display 拉流预览,完全不需要在开发板编译 live555。 提供两套成熟方案: ✅ 方案 A:FFmpeg(最简单,优先推…

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

2026/7/27 8:42:17

一、背景与测试方案 在实际项目交付中,PDF文件合并与版权保护水印的叠加是一个高频但容易被低估的技术需求。典型的处理链路涉及:多源PDF的文件流合并、页面级水印渲染(含透明度混合与图层叠加)、输出文件体积控制。看似简单的操作…

PDF拆分压完图糊了?2026国内免费实测,档案员都在用的组合方案

PDF拆分压完图糊了?2026国内免费实测,档案员都在用的组合方案

2026/7/27 14:56:57

说实话,提到PDF拆分再压缩,我真是被折腾得够呛。 上个月公司年度合同归档,一份300多页的PDF总合同,需要按年份拆分成三个独立文件,再分别压缩到10MB以内方便邮件发送各部门确认。我心想这还不简单?先找个海…

零基础搭建桌面智能体,OpenClaw 2.7.9 分步实操,避开绝大多数部署陷阱

零基础搭建桌面智能体,OpenClaw 2.7.9 分步实操,避开绝大多数部署陷阱

2026/7/28 0:06:55

📌 一、工具核心优势盘点 数据本地存储,安全系数高所有操作日志、文档资料均保存在本机,不会上传至云端,能够有效保护企业文件与个人隐私,规避数据泄露风险。 上手简单,零编程门槛采用全图形化可视化界面&…

计算机毕业设计之基于springboot的购物平台设计与实现

计算机毕业设计之基于springboot的购物平台设计与实现

2026/7/28 0:06:55

由于移动应用技术的持续性的快速发展,现实生活中人们大多数都是通过移动手机、电脑等智能设备来完成生活中的事务。因此,许多的人工传统行业也开始与互联网结合,不再一味的依靠人工手动,努力打造半自动数字化甚至是全自动数字化模…

豆包AI绘图提示词失效真相:NLP模型层token截断机制首次披露,3招绕过字数限制

豆包AI绘图提示词失效真相:NLP模型层token截断机制首次披露,3招绕过字数限制

2026/7/28 0:06:55

更多请点击: https://codechina.net 第一章:豆包AI绘图提示词失效现象全景扫描 近期大量用户反馈,豆包(Doubao)AI绘图功能对常规提示词(Prompt)响应异常:语义明确的指令被忽略、中英…