跟我学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命令提交的暂存区的文件,会保存到本地仓库。…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...