跟我学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命令提交的暂存区的文件,会保存到本地仓库。…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...
