跟我学C++中级篇——Design Patterns的通俗说法
一、设计模式
Design patterns,软件设计模式,它是什么?很多初学者会被这种高大上的东西给唬住。其实,所有的书籍上都说得很清楚,只是它们把这种说法说得很高大上而已。举个简单例子,在抖音上经常可以看到介绍对象问对方是干啥工作的,对方说是什么精密仪器定位啥啥的等等,其实就是一个修家电的。
设计模式其实也类似,它其实不是什么高大上的技术,它只是编码前辈们在编码的实践中发现,有很多种情况下,都可以用一类解决方法来解决问题。特别是当初软件的应用基本都很专业和定向,不象现在如此普及,所以解决起来也容易形成一些固定的形式。因此,就总结出来了那些种设计模式。
给大家说一个农业的例子就明白了,早年种小麦,由于土地、肥料、亩产等原因,种小麦需要什么“两密一稀、三密一稀,四秘一稀”等等。这其实就类似于农业上的设计模式。明白了吧,所以模式,就是固定的模型的意思。它的意思就是有一般意义,可简单重复。所以千万不要对设计模式有神秘感。
二、作用
现实世界和虚拟世界都是千变万化的,但万变不离其宗,大抵还是要遵循一定的规律的。这种规律,在数学上可以是定理,在物理上是定律。而在软件程序中,如果解决某种逻辑使用的方法或手段一致,则可以抽象成设计模式。
刚刚说过了,设计模式的一个重要的特点就是可重复性,也就是说,这种编码的手段是脱离开语言本身的,是一种解决问题的思路的实现。它是一种解决类似问题的方法或者思想的具体的指导落地形式。具有很强的理论和实践性,或者说理论和实践的结合性。它既从实践中反复重复的问题中抽象出可重用的方法,又可以用这种可具体实践的可重用的方法去解决实际问题。这话有点拗口,但仔细一想就明白了。
举一个简单例子,你有一个指定大小的扳手,它既可以拧水管上的同样大小的螺丝,也可以拧机器上的同样大小 的螺丝,推广开来,只要是相同大小的螺丝,无论这个螺丝在哪儿,都可以用它来拧。
那么,既然设计模式这么好用,它可以为编码者带来什么好处呢?答案显而易见:
1、不用动更多的脑子去解决相同的问题,也不用考虑其中的一些细节问题。因为前辈们都已经给解决了。这就是最重要的简单性。
2、既然是总结出来的模式,那么其中的绝大多数坑甚至全部坑都已填好,因此代码质量得到提高,进而提高了系统的稳定必性。
3、可重用的手段甚至是代码,提高了代码的利用率和开发的效率。这个就不用多言了吧。
说得再通俗一些,就是想得少,干得多,效率高,质量好。哪个不高兴,不管是东家还是打长工短工的,都高兴啊。但不要迷信设计模式,这些经验都是有适应场景的,不懂就乱来,很可能会事倍功半。还是那句话,没有一种东西能包打天下。
三、例程
这方面的例程非常多,这里简单上一个,大家知道那么个意思就可以了。具体的可以参看网上的资料和相关书籍:
//observer.h
#include <iostream>
class Observer {
public:Observer() {}virtual ~Observer() {}virtual void Change() {}
};class ObserverA : public Observer {void Change() { std::cout << "A Change call!" << std::endl; }
};class ObserverB : public Observer {void Change() { std::cout << "B Change call!" << std::endl; }
};//main.cpp
#include "observer.h"
#include <algorithm>
#include <iostream>
#include <vector>class Message {
public:void Push(Observer *o) { obs.emplace_back(o); };void Pop(Observer *o) { obs.erase(std::remove(obs.begin(), obs.end(), o), obs.end()); }void MsgUpdate() {for (auto o : obs) {o->Change();}}private:std::vector<Observer *> obs;
};int main() {Observer *b1 = new ObserverA();Observer *b2 = new ObserverB();Message msg;msg.Push(b2);msg.Push(b1);msg.MsgUpdate();msg.Pop(b1);msg.MsgUpdate();delete b2;delete b1;return 0;
}
很简单的一个观察者模式的例程。上面的例程其实有进一步优化的余地,比如采用函数式语言的链式调用,大家有兴趣的可以自己搞一搞。
四、总结
虽然在书籍上和网上有很多设计模式的特点,比如什么面向对象编程思想,可维护可扩展等等。其实就这是前面说的,说得高大上而已。一个简单就代表了可维护性,暗含了可扩展,简单的东西本一般来说容易扩展,而复杂的东西,理解都需要很长时间,怎么容易扩展?同样,简单可重复的东西自然就灵活,其它情况也基本如此。
学习,要抓住问题的本质,不是说其它的东西不重要,而是抓住本质后,再学习其它的特点,就非常容易弄明白和记清楚。
相关文章:
跟我学C++中级篇——Design Patterns的通俗说法
一、设计模式 Design patterns,软件设计模式,它是什么?很多初学者会被这种高大上的东西给唬住。其实,所有的书籍上都说得很清楚,只是它们把这种说法说得很高大上而已。举个简单例子,在抖音上经常可以看到介…...
消息队列原理面试题及参考答案
什么是消息队列? 消息队列是一种在不同应用程序组件或者系统之间进行异步通信的中间件技术。它就像是一个信息的 “中转站”。从技术层面来讲,消息队列主要由消息生产者、消息队列本身和消息消费者这几个核心部分构成。 消息生产者负责创建消息并将其发送到消息队列中。这些消…...

有序数组的平方(leetcode 977)
一个数组,返回一个所有元素的平方之后依然是一个有序数组。(数组中含负数) 解法一:暴力解法 所有元素平方后再使用快速排序法重新排序,时间复杂度为O(nlogn)。 class Solution { public:vector<int> sortedSqu…...

网页抓取API,让数据获取更简单
网页抓取的过程通常分为以下步骤,尤其是在面对静态网页时: 获取页面 HTML:使用 HTTP 客户端下载目标页面的 HTML 内容。解析 HTML:将下载的 HTML 输入解析器,准备提取内容。提取数据:利用解析器功能&#…...

23.<Spring图书管理系统(强制登录版本)>
在前面两篇,我们基本上实现了图书管理系统所有的功能,但是我们发现没有登录也能对其进行修改。这是非常不安全的。因此这篇文章我们学习如何进行强制登录。只有登录进去才能进行操作。 这不是一个对外开放的项目 这篇文章我们将改写图书管理系统为强制登…...

【插件】重复执行 pytest-repeat
安装 pip3 install pytest-repeat 用法 1.命令行 pytest --count num pytest --count 32.装饰器 pytest.mark.repeat(num) #num运行次数 pytest.mark.repeat(5)#执行结果如下:...
pip/conda install bugs汇总
DNSResolutionError 一直不行,惯防火墙还是不行,可能导致漏洞了; 解决方案: reboot下次try可以刷新DNS缓存: resolvectl flush-cachespip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host‘mirrors.a…...

通过shell脚本分析部署nginx网络服务
通过shell脚本分析部署nginx网络服务 1.接收用户部署的服务名称 [rootlocalhost xzy]# vim 1.sh [rootlocalhost xzy]# chmod x 1.sh [rootlocalhost xzy]# ./1.sh2.判断服务是否安装 已安装;自定义网站配置路径为/www;并创建共享目录和网页文件&…...

Java基础——继承和多态
目录 一、继承 继承的定义: 继承的基本用法: 如何调用父类的方法? 二、多态 多态性的好处 多态中的强制类型转换: 包的命名规则——域名倒叙 一、继承 继承的定义: 继承是面向对象编程中的一种机制,…...
长江存储嵌入式面试题及参考答案
构造函数、析构函数可以为虚函数吗,为什么? 构造函数最好不要是虚函数。原因如下: 从对象的生命周期角度来看,虚函数的调用是通过虚函数表(vtable)来实现的。而在构造函数执行的时候,对象还没有完全构造好,vtable 可能还没有被正确地初始化。如果构造函数是虚函数,在…...

WordPress设置自动更新CSS版本号
WordPress 通常会在引用 CSS 文件时添加版本号参数(?verx.x.x)。如果版本号未更新,浏览器可能继续加载旧的文件。 解决方法:确保你在 functions.php 文件中正确加载了 CSS 文件,并动态更新版本号。例如在functions.p…...

【Qt聊天室】客户端实现总结
目录 1. 项目概述 2. 功能实现 2.1 主窗口设计 2.2 功能性窗口 2.3 主界面功能实现 2.4 聊天界面功能实现 2.5 个人信息功能开发 2.6 用户信息界面设置功能 2.7 单聊与群聊 2.8 登录窗口 2.9 消息功能 3. 核心设计逻辑 3.1 核心类 3.2 前后端交互与DataCenter 4…...

服务器数据恢复—raid5阵列故障导致上层系统分区无法识别的数据恢复案例
服务器数据恢复环境: 某品牌DL380服务器,服务器中三块SAS硬盘组建了一组raid5阵列。服务器安装Windows Server操作系统,划分了3个分区,D分区存放数据库,E分区存放数据库备份。 服务器故障: RAID5阵列中有一…...

mysql bin log分析
centos7 部署collabora office (yum版 与 docker)_collabora office部署-CSDN博客 1.下载polardb的bin log文件 show binary logs; mysqlbinlog -u 用户名 -p -h 地址 --read-from-remote-server --raw mysql-bin.001768 mysqlbinlog --no-defaults --databasexxx --base64-…...
深入理解 Vue 3 中的 emit
深入理解 Vue 3 中的 emit 在 Vue 3 中,组件通信是开发中非常重要的一部分,其中通过 emit 实现父子组件通信是最常见的方式之一。emit 的作用是:子组件可以通过触发自定义事件将数据传递给父组件。 在本篇文章中,我们将从以下几…...
#lwIP 的 Raw API 使用指南
1. 简介 lwIP(Lightweight IP)是一个为嵌入式系统设计的开源轻量级 TCP/IP 协议栈。它旨在提供尽可能小的内存占用和高效的性能,适用于资源受限的设备,如物联网设备、路由器和工业控制系统。lwIP 支持多种协议,包括 I…...

Elasticsearch开启认证及kibana密码登陆
Elasticsearch不允许root用户运行,使用root用户为其创建一个用户es,为用户es配置密码,并切换到es用户。 adduser elastic passwd elastic su elasticElasticsearch(简称ES)是一个基于Lucene的搜索服务器。它提供了一个分布式、多用户能力的全文搜索引擎,基于RESTful web…...

【论文阅读】Large Language Models for Equivalent Mutant Detection: How Far Are We?
阅读笔记:Large Language Models for Equivalent Mutant Detection: How Far Are We? 1. 来源出处 本文发表于《ISSTA’24, September 16–20, 2024, Vienna, Austria》会议,由Zhao Tian, Honglin Shu, Dong Wang, Xuejie Cao, Yasutaka Kamei和Junji…...
vue2 面试题带答案,万字总结
1. 什么是 vue Vue 是一套用于构建用户界面的渐进式框架。Vue.js 的主要特点:渐进式框架、声明式渲染、组件化、响应式数据绑定等; 2、MVC 和 MVVM 区别 MVC 是模型(model)-视图(view)-控制器(controller),控制器负责…...
git的常用用法(最简精华版)
一、工作区域(工作区,暂存区,本地仓库) 1、工作区 当前正在使用的文件 2、暂存区 已使用add命令提交的工作区的文件,会保存到暂存区 3、本地仓库 已使用commit命令提交的暂存区的文件,会保存到本地仓库。…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...