23种设计模式之C++实践(一)
23种设计模式之C++实践
- 1. 简介
- 2. 基础知识
- 3. 设计模式
- (一)创建型模式
- 1. 单例模式——确保对象的唯一性
- 1.2 饿汉式单例模式
- 1.3 懒汉式单例模式
- 比较
- IoDH
- 单例模式总结
- 2. 简单工厂模式——集中式工厂的实现
- 简单工厂模式总结
- 3. 工厂方法模式——多态工厂的实现
- 工厂方法模式总结
- 4. 抽象工厂模式——产品族的创建
- 抽象工厂模式总结
- 5. 原型模式——对象的克隆
- 原型模式总结
- 6. 建造者模式——复杂对象的创组装与创建
- 建造者模式总结
1. 简介
设计模式是一门技术,更是一门艺术,它为构建可维护性和可复用性俱佳的软件而诞生。
2. 基础知识
- 设计模式(Design Pattern):是一套被反复使用的,多数人知晓的,经过分类编目的代码设计经验的总结,使用设计模式是为了可以重用代码,让代码更容易被理解并提高代码的可靠性。
- UML(United Modeling Language):
- 类
- 关联关系(实线):通常将一个类的对象作为另一个类的成员变量。
- 双向关联
- 单向关联
- 自关联
- 多重性关联
- 聚合关系(空心菱形直线):成员是整体的一部分,但是成员可以脱离整体存在。通常通过
set()
函数初始化成员变量。 - 组合关系(实心菱形直线):整体控制成员的声明周期,整体不存在,则成员不存在。通常通过构造函数初始化成员变量。
- 依赖关系(带箭头虚线):类的改变影响到使用该类的其他类,则其他类依赖该类。通常通过将一个类的对象作为另一个类中方法的参数体现。
- 泛化关系/继承关系(空心三角形实线):父类与子类。
- 接口与实现关系(空心三角形虚线):在接口类中声明抽象函数,在实现类中实现函数。
- 关联关系(实线):通常将一个类的对象作为另一个类的成员变量。
- 类
- 面向对象设计原则:
- 单一职责原则(Single Responsibility):一个类只负责一个功能领域中的相应职责。或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。高内聚,低耦合。
- 开闭原则(Open-Closed Principle,OCP):一个软件实体应该对外扩展开放,对修改关闭。即软件实体尽量在不修改原有代码的基础下进行扩展。抽象化。
- 里氏代换原则(Liskov Substitution Principle,LSP):所有引用父类的地方必须能透明地使用其子类的对象。父类抽象化
- 依赖倒转原则(Dependency Inversion Principle,DIP):抽象不应该依赖于细节,细节应该依赖于抽象。即针对接口编程,而不是针对实现编程。参数抽象化。
- 接口隔离原则(Interface Segregation Principle,ISP):使用多个专用的接口,而不适用单一的总接口,即客户端不应该依赖那些它不需要的接口。
- 合成复用原则(Composite Reuse Principle,CRP):尽量使用对象组合,而不是继承来达到复用的目的。
- 迪米特法则/最少知识原则(Law of Demeter/Least Knowledge Principle,LoD/LKP):一个软件实体应该尽可能少的与其他实体发生相互作用。
3. 设计模式
(一)创建型模式
1. 单例模式——确保对象的唯一性
-
单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类成为单例类,它提供全局访问的方法。
-
要点:
-
某个类只能有一个实例
-
它必须自行创建这个实例
-
它必须自行向整个系统提供这个实例
-
-
结构图:
-
使用场景实例
Windows任务管理器
在一个Windows系统中,任务管理器存在唯一性。
-
代码实例
// TaskManager.h class TaskManager {private:/*** @brief 初始化窗口**/TaskManager() {}public:/*** @brief 显示进程**/void displayProcesses();/*** @brief 显示服务**/void displayServices();private:static TaskManager* tm;public:static TaskManager* getInstance(); };// TaskManager.cpp TaskManager* TaskManager::tm = nullptr;void TaskManager::displayProcesses() {printf("显示进程……\n");return; } void TaskManager::displayServices() {printf("显示服务……\n");return; }TaskManager* TaskManager::getInstance() {if (tm == nullptr) {tm = new TaskManager();}return tm; }
-
代码测试
-
测试代码:
int main(int argc, char** argv) {printf("I'm Singleton Pattern!\n");// begin testSingleTonNS::TaskManager* tm = SingleTonNS::TaskManager::getInstance();tm->displayProcesses();tm->displayServices();// end testreturn 0; }
-
输出
I’m Singleton Pattern!
显示进程……
显示服务……
-
1.2 饿汉式单例模式
-
饿汉式单例模式(Eager Singleton):在定义静态变量的时候实例化单例类,因此在类加载时就已经创建了单例对象
-
结构图
-
代码示例
// TaskManager.hclass TaskManager {private:/*** @brief 初始化窗口**/TaskManager() {}public:/*** @brief 显示进程**/void displayProcesses();/*** @brief 显示服务**/void displayServices();private:static TaskManager* tm;public:static TaskManager* getInstance();};// TaskManager.cpp// 饿汉式单例模式初始化TaskManager* TaskManager::tm = new TaskManager();void TaskManager::displayProcesses() {printf("显示进程……\n");return;}void TaskManager::displayServices() {printf("显示服务……\n");return;}TaskManager* TaskManager::getInstance() {return tm;}
1.3 懒汉式单例模式
- 见单例模式实现方式。
比较
-
饿汉式单例类
-
优点
-
无需考虑多线程访问问题,可以确保实例的唯一性
-
调用速度与反应时间更快
-
-
缺点
-
资源利用效率更低
-
加载时间更长
-
-
-
懒汉式单例类
- 优点
- 延迟加载,无需一直占用系统资源
- 缺点
- 必须处理好多线程同时访问的问题,可能引起性能受影响
- 优点
IoDH
- 有没有一种方法,能够将两种单例的缺点都克服,而将两者的优点合二为一呢?答案是肯定的,即Initialization on Demand Holder技术
- IoDH:在单例类中增加一个静态内部类,在该内部类中,创建单例对象,再将该单例对象通过
getInstance()
方法返回给外部使用。 - 使用IoDH,既可以实现延迟加载,又可以保证线程安全,不影响系统性能,但是与编程语言本身的特性相关,很多面向对象语言不支持IoDH,例如C++。支持的语言有Java。
单例模式总结
- 优点
- 提供了对唯一实例的受控访问。
- 节约系统资源
- 允许可变数目的实例。
- 缺点
- 没有抽象层,扩展较为困难
- 职责过重,一定程度上违反了单一职责原则。
- 很多面向对象语言(例如Java,C#)的运行环境都提供了自动垃圾回收技术,因此,如果实例化的共享对象长期不被利用,会自动销毁并回收资源,下次利用时重新实例化,这将导致共享的单例对象状态的丢失。
- 适用场景
- 系统只需要一个实例对象
- 客户调用类的单个实例只允许使用一个公共访问点。
2. 简单工厂模式——集中式工厂的实现
-
简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建类的实例通常具有共同的父类。
-
要点:
- 当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
-
结构图:
-
适用场景实例
图标库:为应用系统提供各种不同外观的图表,例如柱状图、饼状图、折线图等等
-
代码示例
// Chart.h
/*** @brief 图表类接口**/
class Chart {public:virtual void display() = 0;
};/*** @brief 柱状图**/
class HistogramChart : public Chart {public:HistogramChart();void display() override;
};/*** @brief 饼状图**/
class PieChart : public Chart {public:PieChart();void display() override;
};/*** @brief 折线图**/
class LineChart : public Chart {public:LineChart();void display() override;
};// ChartFactory.h
class ChartFactory {public:static Chart* getChart(std::string type);
};// Chart.cpp
HistogramChart::HistogramChart() { printf("创建柱状图!\n"); }void HistogramChart::display() {printf("展示柱状图!\n");return;
}PieChart::PieChart() { printf("创建饼状图!\n");
相关文章:
23种设计模式之C++实践(一)
23种设计模式之C++实践 1. 简介2. 基础知识3. 设计模式(一)创建型模式1. 单例模式——确保对象的唯一性1.2 饿汉式单例模式1.3 懒汉式单例模式比较IoDH单例模式总结2. 简单工厂模式——集中式工厂的实现简单工厂模式总结3. 工厂方法模式——多态工厂的实现工厂方法模式总结4.…...
华为OD机试 - 园区参观路径(Java JS Python C)
题目描述 园区某部门举办了Family Day,邀请员工及其家属参加; 将公司园区视为一个矩形,起始园区设置在左上角,终点园区设置在右下角; 家属参观园区时,只能向右和向下园区前进,求从起始园区到终点园区会有多少条不同的参观路径。 输入描述 第一行为园区的长和宽; 后…...
【ARM Trace32(劳特巴赫) 使用介绍 12 -- Trace32 常用命令之 d.dump | data.dump 介绍】
文章目录 Trace32 常用命令之 d.dump | data.dump 介绍1 字节显示 (Byte)4 字节显示(word)8 字节显示(通常long)十进制显示显示指定列数显示地址范围内的值 Trace32 常用命令之 d.dump | data.dump 介绍 在 TRACE32 调试环境中&a…...
【Git】Git撤销操作
记录一下,方便后续查找,不全,后续再做补充。 丢弃当前工作区未提交的修改 # 丢弃所有修改 git checkout .# 丢弃某个文件修改 git checkout 文件名丢弃本地已经提交的代码 (1)撤销最近一次提交 如果我们在最近一次提…...
改造python3中的http.server为简单的文件上传下载服务
改造 修改python3中的http.server.SimpleHTTPRequestHandler,实现简单的文件上传下载服务 simple_http_file_server.py: # !/usr/bin/env python3import datetime import email import html import http.server import io import mimetypes import os …...
Fiddler抓包工具之fiddler的composer可以简单发送http协议的请求
一,composer的详解 右侧Composer区域,是测试接口的界面: 相关说明: 1.请求方式:点开可以勾选请求协议是get、post等 2.url地址栏:输入请求的url地址 3.请求头:第三块区域可以输入请求头信息…...
14、pytest像用参数一样使用fixture
官方实例 # content of test_fruit.py import pytestclass Fruit:def __init__(self, name):self.name nameself.cubed Falsedef cube(self):self.cubed Trueclass FruitSalad:def __init__(self, *fruit_bowl):self.fruit fruit_bowlself._cube_fruit()def _cube_fruit(s…...
C++ Primer Plus第十三章笔记
目录 基类 构造函数:访问权限的考虑 1.2 派生类和基类之间的特殊关系 继承:is-a关系 多态公有继承 静态联编和动态联编 指针和引用类型的兼容性 虚成员函数和动态联编 虚函数的注意事项 构造函数 析构函数 友元 没有重新定义 重新定义将隐…...
【JavaEE】单例模式
作者主页:paper jie_博客 本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文于《JavaEE》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造&…...
第十五届蓝桥杯模拟赛(第二期 C++)
俺自己做的噢,还未核实答案,若有差错,望斧正。 第一题 小蓝要在屏幕上放置一行文字,每个字的宽度相同。小蓝发现,如果每个字的宽为 36 像素,一行正好放下 30 个字,字符之间和前后都没有任何空隙…...
关于Unity中字典在Inspector的显示
字典在Inspector的显示 方法一:实现ISerializationCallbackReceiver接口 《unity3D游戏开发第二版》记录 在编辑面板中可以利用序列化监听接口特性对字典进行序列化。 主要继承ISerializationCallbackReceiver接口 实现OnAfterDeserialize() OnBeforeSerialize() …...
使用Plex结合cpolar搭建本地私人媒体站并实现远程访问
文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 用手机或者平板电脑看视频,已经算是生活中稀松平常的场景了,特别是各…...
svn合并冲突时每个选项的含义
合并冲突时每个选项的含义 - 这个图片是 TortoiseSVN(一个Subversion(SVN)客户端)的合并冲突解决对话框。当你尝试合并两个版本的文件并且出现差异时,你需要解决这些差异。这个对话框提供了几个选项来处理合并冲突&…...
指针、数组与函数例题3
1、字符串复制 题目描述 设计函数实现字符串复制功能,每个字符串长度不超过100,不要使用系统提供的strcpy函数 输入要求 从键盘读入一个字符串到数组b中,以换行符结束 输出要求 将内容复制到另一个数组a中,并分别输出数组a和…...
ThreeJs样例 webgl_shadow_contact 分析
webgl_shadow_contact 官方样例中,对阴影的渲染比较特殊,很值得借鉴,学习渲染阴影的思路;这个例子中对阴影的渲染,并没有使用任何光源,没有用shadowmap的常规方式 渲染阴影;而是使用了深度材质T…...
Nginx(缓冲区)
先来思考一个问题,接入Nginx的项目一般请求流程为:“客户端→Nginx→服务端”,在这个过程中存在两个连接:“客户端→Nginx、Nginx→服务端”,那么两个不同的连接速度不一致,就会影响用户的体验(…...
MQTT协议理解并实践
MQTT是一个轻量的发布订阅模式消息传输协议,专门针对低带宽和不稳定网络环境的物联网应用设计 MQTT协议根据主题来分发消息进行通信,支持通配符匹配,可以低开销的使用数百万Topic进行一对一,一对多双向通信。 协议特点 1. 开放…...
实现一个简单的网络通信下(udp)
时间过去好久了,先回忆一下上一篇博客的代码!! 目前来看,我们客户端发一条消息,我服务器收到这一条消息之后呢,服务器也知道了是谁给我发来的消息,紧接这就把这条消息放进buffer当中,…...
Linux中office环境LibreOffice_7.6.2下载
阿里云盘:LibreOffice_7.6.2 使用:下载的文件为exe文件,双击exe文件即可获取到文件 LibreOffice_7.6.2安装: 解压:tar -zxvf LibreOffice_7.6.2_Linux_x86-64_rpm.tar.gz 移动到RPMS目录:cd LibreOffice_7…...
Linux快捷控制
Linux快捷控制 工具安装 yum -y install lrzsz wget curl net-tools git防火墙 systemctl status firewalld.service systemctl stop firewalld.service systemctl disable firewalld.service宝塔 yum install -y wget && wget -O install.sh https://download.bt.…...
免费插件集-illustrator插件-Ai插件-重复复制-单一对象页面排版
文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件>重复复制4.总结 1.介绍 本文介绍一款免费插件,加强illustrator使用人员工作效率,进行制卡专用分层分色。首先从下载网址下载这款插件 https://download.csdn.net/download/m0_67316550/8789050…...
GO基础之变量与常量
标识符与关键字 标识符 在编程语言中标识符就是程序员定义的具有特殊意义的词,比如变量名、常量名、函数名等等。 Go语言中标识符由字母数字和_(下划线)组成,并且只能以字母和_开头。 举几个例子:abc, _, _123, a123。 关键字 关键…...
Docker Compose简单入门
Docker Compose 简介 Docker Compose 是一个编排多容器发布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。 Docker Compose 真正的作用是在一个文件(docker-compose.yml)中定义并运…...
使用 PHPMailer 实现邮件的实时发送
💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 今天我们利用GitHub上20K星星的项目 PHPMailer…...
在Spring Boot中使用JavaMailSender发送邮件
用了这么久的Spring Boot,我们对Spring Boot的了解应该也逐步进入正轨了,这篇文章讲的案例也在我们的实际开发中算是比较实用的了,毕竟我们完成注册功能和对用户群发消息,都可以采用到邮箱发送功能,往下看,…...
python动态圣诞下雪图
运行图片 代码 import pygame import random# 初始化Pygame pygame.init()# 创建窗口 width, height 800, 600 screen pygame.display.set_mode((width, height)) pygame.display.set_caption(Christmas Tree)# 定义颜色 GREEN (34, 139, 34) RED (255, 0, 0) WHITE (255…...
随心玩玩(十)git
写在前面:研究生一年多了,一直浑浑噩噩的,在深度学习的泥潭挣扎了好久,终于走出了精神内耗的泥潭…好久没有写博客了,决定重新捡起来…记录一下学习吧~ 之前写了一篇git的博客,【github 从0开始的基本操作…...
每日一练【盛最多水的容器】
一、题目描述 11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&…...
Linux C语言 38-进程间通信IPC之信号
Linux C语言 38-进程间通信IPC之信号 本节关键字:C语言 进程间通信 信号量 semaphore 相关库函数:sem_init、sem_post、sem_wait、sem_destroy 提示:先做内容框架梳理,后期进行完善补充! 什么是信号量? …...
前端使用 xlsx.js 工具读取 excel 遇到时间日期少 43 秒的解决办法
在使用 xlsx 读取 excel 的时间格式的数据时,如 ‘2023-11-30’,‘2023/11/30’ ,默认会读取一串数字字符串,如:‘45260’,此时需要在 read 的时候传入一个配置项: import { read } from xlsxc…...
怎么做免费的网站空间/宜昌网站seo收费
https://www.luogu.org/problem/show?pid1205 大大大大大大枚举! 通过纸上画图来找各个情况中点与点的对应坐标关系。 还需要注意的问题:题目要求序号尽量靠前。 #include<iostream> #include<cstdio> #include<cstring> #include&…...
制作灯笼需要什么材料/搜索引擎优化技术
目标 1. 掌握常用的元素操作方法 2. 掌握常用的操作浏览器方法 3. 知道常用的获取元素信息的方法 1. 元素操作 为什么要学习操作元素的方法? 1. 需要让脚本模拟用户给指定元素输入值 2. 需要让脚本模拟人为删除元素的内容 3. 需要让脚本模拟点击操作 1.1 元…...
全品类供应链平台/佛山网站设计实力乐云seo
F(x,m) 代表一个全是由数字x组成的m位数字。请计算,以下式子是否成立: F(x,m) mod k ≡ c Input 第一行一个整数T,表示T组数据。 每组测试数据占一行,包含四个数字x,m,k,c 1≤x≤9 1≤m≤1010 0≤c<k≤10,000 Output 对于每组数…...
做网站的图片需要多少钱/推广赚钱的软件
最近在做报表,跟数据库打交道的比较多,所以特意来总结一下mysql的联合查询; 查询常用的字句 where(条件查询)、having(筛选)、group by(分组)、order by(排序)、limit&am…...
b2b网站大全黄页8禁/十大销售管理软件排行榜
Afly | 2006-7-29 | Fanfou 勇敢、专注、孤独、坚定、团结、残酷 ……这就是狼的世界。 在这个世界里,没有对,没有错,只有成功。没有正义,没有罪恶,只有一个目的:生存…… 用一种动物的特征形象地表达企业…...
建设厅网站怎么打印不出来/广州头条新闻最新
window.alert("hello world.");转载于:https://www.cnblogs.com/Kennytian/archive/2007/02/26/656748.html...