从C向C++28——设计模式

news2024/11/15 12:03:08

一.设计模式

1.设计模式理解

​ C++程序设计模式是针对在C++编程中常见问题的通用、可重用的解决方案。设计模式主要是在软件工程领域,特别是在面向对象编程中发展起来的,它们提供了一种标准的术语和解决方案,可以帮助程序员更好地设计软件架构和组件。

设计模式通常分为三大类,总共有23种,它们分别是:

  1. 创建型模式(Creational Patterns):这类模式处理对象创建机制,旨在提高对象的创建过程的灵活性和重用性。它们共有5种:
    • 工厂方法模式(Factory Method):定义一个接口用于创建对象,但让子类决定实例化哪个类。
    • 抽象工厂模式(Abstract Factory):创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    • 单例模式(Singleton):确保一个类只有一个实例,并提供一个全局访问点。
    • 建造者模式(Builder):将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
    • 原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
  2. 结构型模式(Structural Patterns):这类模式关注类和对象组合的方式,用于形成更大的结构。它们共有7种:
    • 适配器模式(Adapter):将一个类的接口转换成客户期望的另一个接口。
    • 装饰器模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
    • 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。
    • 外观模式(Facade):为一组复杂的子系统提供一个统一的接口。
    • 桥接模式(Bridge):将抽象部分与实现部分分离,使它们都可以独立地变化。
    • 组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。
    • 享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象。
  3. 行为型模式(Behavioral Patterns):这类模式负责对象之间的有效沟通和责任分配,有助于提高系统的灵活性。它们共有11种:
    • 策略模式(Strategy):定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。
    • 模板方法模式(Template Method):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
    • 观察者模式(Observer):对象间的一对多依赖关系,当一个对象改变状态,所有依赖于它的对象都会得到通知并自动更新。
    • 状态模式(State):允许对象在内部状态改变时改变它的行为。
    • 命令模式(Command):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
    • 责任链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免了请求发送者和接收者之间的耦合关系。
    • 中介者模式(Mediator):用一个中介对象来封装一系列的对象交互。
    • 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中各个元素, 而又不暴露该对象的内部表示。
    • 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
    • 备忘录模式(Memento):捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
    • 解释器模式(Interpreter):为语言创建解释器,用来解释该语言中的句子。

2.类图和UML

​ 类图是面向对象设计中用来描述系统中类的结构和类之间关系的一种静态结构图。它展示了系统的静态视图,即在一个特定的时间点,系统中的类、接口、协作以及它们之间的关系。

​ 类图用于描述设计模式的原因是,设计模式主要是在面向对象编程的背景下定义的,它们依赖于类和对象的结构和关系。通过类图,设计模式的结构可以直观地表示出来,使得设计意图更加清晰,有助于理解和交流。

​ UML(统一建模语言)是表示类图的一种标准方式。UML提供了一套丰富的符号和图形,用于表示面向对象系统中的各种元素,包括类、接口、属性、方法、关联、泛化(继承)等。UML类图是设计人员和开发人员之间沟通的重要工具,因为它提供了一种通用的、易于理解的语言来描述系统的设计。

3.认识UML类图

image-20240527152631141

可以看到该图分为上中下三部分:上层是类名(红色),中间层是属性(类的成员变量,橙色),下层是方法(类的成员函数,蓝色)。

  • 可见性:+ 表示public、# 表示protected、- 表示private、__(下划线)表示static

  • 属性的表示方式:【可见性】【属性名称】:【类型】= { 缺省值,可选 }

  • 方法的表示方式:【可见性】【方法名称】(【参数名 : 参数类型,……】):【返回值类型】

如果我们定义的类是一个抽象类(类中有纯虚函数),在画UML类图的时候,类名需要使用斜体显示。

4.类和类之间的关系

UML描述类之间的关系:

  • 继承也叫作泛化(Generalization),用于描述父子类之间的关系,父类又称为基类或者超类,子类又称作派生类。在UML中,泛化关系用带空心三角形的实线来表示,其中三角形的箭头指向的是父类,实现末尾连接的是派生类。

  • 类之间的关联关系有三种,分别是:单向关联、双向关联、自关联

    • 单向关联指的是关联只有一个方向,比如每个孩子(Child)都拥有一个父亲(Parent),可以理解为一种继承,如果是单向关联,使用的连接线是带单向箭头的实线, 哪个类作为了当前类的成员变量,那么箭头就指向哪个类。上面孩子有父亲,所以箭头是孩子指向父亲
    • 双向关联指的是两个类互相包含,例如孩子有父亲,父亲也有孩子,在画UML类图的时候,一般使用没有箭头的实线来连接有双向关联关系的两个类,这两个类的对象分别作为了对方类的成员变量。
    • 自关联指的就是当前类中包含一个自身类型的对象成员,这在链表中非常常见,单向链表中都会有一个指向自身节点类型的后继指针成员,而双向链表中会包含一个指向自身节点类型的前驱指针和一个指向自身节点类型的后继指针。一般使用带箭头的实线来描述自关联关系,箭头出来还是指向自己。
  • 聚合(Aggregation)关系表示整体与部分的关系。在聚合关系中,成员对象是整体的一部分,但是成员对象可以脱离整体对象独立存在。在UML中,聚合关系用带空心菱形直线表示,下面举两个聚合关系的例子:汽车(Car)与 引擎(Engine)、轮胎(Wheel)、车灯(Light)

  • 组合(Composition)关系也表示的是一种整体和部分的关系,但是在组合关系中整体对象可以控制成员对象的生命周期,一旦整体对象不存在,成员对象也不存在,整体对象和成员对象之间具有同生共死的关系。在UML中组合关系用带实心菱形的直线表示,下面举两个组合关系的例子:头(Head)和 嘴巴(Mouth)、鼻子(Nose)、耳朵(Ear)、眼睛(Eye)

  • 依赖(Dependency)关系是一种使用关系,特定事物的改变有可能会影响到使用该事物的其他事物,在需要表示一个事物使用另一个事物时使用依赖关系,大多数情况下依赖关系体现在某个类的方法使用另一个类的对象作为参数。在UML中,依赖关系用带箭头的虚线表示,由依赖的一方指向被依赖的一方,

二.创建型模式

1.简单工厂模式

简单工厂模式并不属于创建型模式里的一种,之所以在这里介绍是为了更好的理解后面的设计模式。

通过场景来理解:有一些类A、B……,如果现在要创建一个A类的对象,但是其构造实例特别复杂,比如先读取文件,再读取数据库,再……反正一系列复杂操作,导致构建实例非常复杂,同理其余类也类似,那么可以有这么一种方式,例如先构造一个工厂类,封装一个构造方法,传入你要构建类的参数,这样工程就可以自动建立对应对象的实例。

优点:

  • 客户端调用与具体实现类解耦
  • 对于某些常见对象比较复杂的,就无需考虑

缺点:

  • 增加新功能是通过修稿源代码实现的,不符合开闭原则
  • 工厂类职责过重,一旦出现问题,大面积受到影响

2.工厂方法模式

工厂方法模式的场景理解:在上面简单工厂模式的场景基础上,每一个类对象的构造分别对应一个具体工厂,这样也可以使用到抽象工厂,每当建立一个类的对象,就new一个对应的具体工厂。

优点:符合开闭性原则

缺点:类增加,工厂也增加,复杂和成本问题

3.抽象工厂模式

image-20240528163440370

抽象工厂模式场景理解:结合上图,其实是提取共同属性,减少具体工厂,来避免工厂方法模式的复杂度问题,而又根据这个属性对应一个具体工厂,相当于简单工厂模式和工厂方法模式的结合。

4.单例模式

单例模式:某个类的对象个数只能为1。

如果要满足类对象只能为1个,那么肯定构造函数不能被多次调用,也就是构造函数私有化。

实现单例模式的步骤:

  • 1.构造函数私有化
  • 2.增加静态私有的当前类的指针变量
  • 3.提供静态对外接口,可以让用户获得单例对象
#include <iostream>
using namespace std;

class A {
private:
	A()
	{
		a = new A;
	}

public:
	static A* getinstance()
	{
		cout << "123" << endl;
		return a;
	}

private:
	static A* a;
};

A* A::a = NULL;

int main()
{
	A::getinstance();
	//A a;      //报错,因为构造函数私有化
	A::getinstance();


	return 0;
}

这只是一个单例模式的例子,并不符合规范,通过外面的公共接口getinstance来初始化。

而实际单例模式创建的时候分为懒汉式和饿汉式:

#include <iostream>
using namespace std;

//懒汉式
class Lazy
{
private:
	Lazy()
	{
		cout << "我是懒汉" << endl;
	}
	static Lazy* getinstance()
	{
		if (lazy == NULL)        //懒汉:如果没有那就建立一个
		{
			lazy = new Lazy;
		}
		return lazy;
	}

private:
	static Lazy* lazy;
};
Lazy* Lazy::lazy=NULL;

//饿汉式
class Hungry
{
private:
	Hungry() { cout << "我是饿汉" << endl; }
	static Hungry* getinstance()
	{
		return hungry;                  //饿汉:类外直接创建了一个
	}

private:
	static Hungry* hungry;
};
Hungry* Hungry::hungry = new Hungry;         

int main()
{
	cout << 123 << endl;

	return 0;
}

懒汉式讲究的是需要的时候再建立,饿汉是讲究的是直接一开始就建立一个对象,通过上述代码我们可以发现,饿汉式在执行main之前就开始运行啦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2085237.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

豆包 MarsCode试用体验

1.前言 豆包 MarsCode 是一款为你提供了AI编程助手和云端集成开发环境来协助你完成编程任务的产品。 2.功能介绍 2.1.豆包 MarsCode 编程助手 豆包 MarsCode 编程助手是豆包旗下的 AI 编程助手&#xff0c;提供以智能代码补全为代表的 AI 功能。它支持主流的编程语言和 IDE…

Luma AI,让你的视频像电影一样精彩!附带使用教程

Luma 视频生成 API 对接说明 随着 AI 的应用变广&#xff0c;各类 AI 程序已逐渐普及。AI 已逐渐深入到人们的工作生活方方面面。而 AI 涉及的行业也越来越多&#xff0c;从最初的写作&#xff0c;到医疗教育&#xff0c;再到现在的视频。 Luma 是一个专业高质量的视频生成平…

tomcat实验

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;Tomcat 具有处理HTML页面的功能&#xff0c;它还是一个Servlet和JSP容器。 下载文件 安装javajdk 解压 …

ComfyUI基础操作教学!小白入门必看!

在我们打开comfyui后会面对一堆节点&#xff0c;那么这些节点都是什么意思呢&#xff1f;今天跟着小元老师来学习一下吧&#xff5e; 一、拆解文生图基本工作流 这个是Comfyui默认的文生图工作流它的基本逻辑是&#xff1a; 条件输入板块——潜空间——像素空间 01 条件输入模…

AiThinkerIDE_V1.5.2工程随意移动地方,路径不能有空格

路径不能有空格&#xff0c;例如usr_sdk不能改为usr sdk IDF_PATH&#xff1a; ${workspace_loc:/AiThinkerProjectForESP}${workspace_loc:/AiThinkerProjectForESP}/examples/get-started/hello_world

2024年入职_转行网络安全,该如何规划呢?

前言 前段时间&#xff0c;知名机构麦可思研究院发布了 《2023年中国本科生就业报告》&#xff0c;其中详细列出近五年的本科绿牌专业&#xff0c;其中&#xff0c;信息安全位列第一。 网络安全前景 对于网络安全的发展与就业前景&#xff0c;想必无需我多言&#xff0c;作为…

C#中的批量引用已有的NuGet包

引言 小伙伴们有没有遇到过一个问题&#xff0c;就是我有一个类库A引用了很多NuGet包&#xff0c;但是到B类库中也需要使用&#xff0c;但是不想一个一个引用&#xff0c;很麻烦&#xff0c;所以我教大家一招&#xff0c;直接复制NuGet包&#xff1a; 第一步&#xff1a; 找…

【开发实战】QT5 + 深度学习六大应用案例

点击这里&#xff0c;即可一键获取六大案例源码与相关资料 QT5 OpenCV4.8 QT5 OpenCV4.8 开发与配置环境搭建&#xff0c;请看博客文章 QT5 OpenCV4 开发环境配置应用演示 深度学习模型部署 深度学习模型部署有很多成熟的框架&#xff0c;当前经常使用的深度学习模型推理…

linux 上传文件报错 -bash: rz:command not found

linux 上传文件报错 -bash: rz:command not found 新创建的纯净虚拟机无法上传文件安装lrzsz 新创建的纯净虚拟机无法上传文件 这个错误表明系统中没有安装 rz&#xff08;上传文件工具&#xff09;命令。 如果是在 CentOS 或 Red Hat 等基于 RPM 的系统上&#xff0c;可以使用…

基于RFID光触发标签的光交箱哑资源管理优化方案

当今数字化高速发展的时代&#xff0c;政企单位对通信服务的质量和可靠性提出了越来越高的要求。光交箱作为通信网络中的关键节点&#xff0c;其哑资源的有效管理对于保障通信的顺畅至关重要。然而&#xff0c;传统的管理方式在面对日益复杂的通信需求时&#xff0c;逐渐暴露出…

PHP多功能投票系统小程序源码社群决策与趣味互动新潮流

&#x1f31f;【引领社群新风尚&#xff0c;一键决策更轻松】&#x1f31f; 你还在为社群活动意见不合而烦恼吗&#xff1f;多功能投票小程序来拯救你的选择困难症&#xff01;无论是团队项目方案、周末出游地点&#xff0c;还是晚餐吃什么的小纠结&#xff0c;只需轻轻一点&a…

蓝牙语音遥控器方案

在智能家居的时代&#xff0c;科技正在改变我们的生活方式。蓝牙语音遥控器&#xff0c;作为智能家居的关键组成部分&#xff0c;正在重新定义用户与设备之间的互动方式。用户对着蓝牙语音遥控器&#xff0c;只要轻说一句话就可以搞定很多复杂的遥控操作&#xff0c;使用非常方…

Flask+LayUI开发手记(五):树型表格实现数据展示与编辑

说起来&#xff0c;树型表格treeTable绝对是后端程序员的巨大福利。要知道&#xff0c;在系统编程中&#xff0c;有父子节点关系的数据真是太多了&#xff0c;随便想一下就可以举出很多例子&#xff0c;比如权限、栏目、机构、产品、科目、货币、行业诸般等等&#xff0c;其实只…

国密起步4:GmSSL3生成证书并使用tls(SM2、SSL)

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 此文介绍如何使用gmssl的tls示…

RCS plot 包内置数据集使用时报错,如何解决?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

【爬虫软件】YouTube评论采集工具

我用Python开发的油管评论批量采集软件。 软件界面&#xff1a; 采集结果&#xff1a; 演示视频&#xff1a; https://www.bilibili.com/video/BV1Ny411z7Wk 完整讲解&#xff1a; https://www.bilibili.com/read/cv35334276

Python进阶01-面向对象基础

零、文章目录 Python进阶01-面向对象基础 1、面向对象编程思想 &#xff08;1&#xff09;编程思想是什么 所谓的编程思想&#xff0c;就是人们利用计算机来解决实际问题的一种思维方式。常见的编程思想有面向过程和面向对象&#xff0c;很多计算机语言的语法各不相同&…

OpenHarmony南向开发:分布式软总线-softbus_tool使用规范

oftbus_tool 是 OpenHarmony 分布式软总线 API 调用测试工具&#xff0c;文件结构如下图所示。 softbus_tool 能够将软总线 interfaces 目录下的一些常用接口集中起来&#xff0c;供设备间搭建一些场景时使用&#xff08;比如设备绑定、BR 组网&#xff0c;BLE 组网&#xff0…

oracle的BITAND()函数用法

BITAND函数是计算两个数据的按位与 如下&#xff1a; 0010 0101 的按位与结果是0000 转为2进制就是0 0010 0011 的按位与结果是0010 转为2进制就是2

linux本地库迁移到阿里云云redis

背景 领导要我把另外一个不同账号的云redis进行同步 想法 阿里云不能直接备份还原redis&#xff0c;需要把备份文件先给搞到本地redis,然后本地redis进行同步到云redis 大概的逻辑是这样 实操 我这里下载的版本是4.0.2,文件如下: redis-shake-linux-amd64.tar.gz github下…