![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
#设计模式/架构设计
文章平均质量分 95
各种设计模式、各种架构设计和一些常见的习惯用法
流星雨爱编程
记录工作的日常,心得体会
展开
-
C++中跨平台类的设计方法
本文从类的设计角度来考虑代码的跨平台性,其实在实现的过程还需要综合考虑平台差异、标准库和第三方库的选择、运行时环境差异的处理、跨平台编译工具的使用、跨平台测试与调试以及跨平台接口设计等多个方面。通过合理的设计和实现,可以大大提高代码的可移植性和复用性,降低维护成本。原创 2024-07-14 18:35:54 · 767 阅读 · 8 评论 -
C++模块化之内部类
在C++中,内部类(Nested Class)是一种相对不太常用但却非常强大的编程工具。就是在一个类内部定义另外一个类,注意此时这个内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。 注意:内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员,不管是public、protected、private。但是外部类不是内部类的友元。原创 2024-07-05 21:47:41 · 967 阅读 · 0 评论 -
Qt读取ini格式配置文件的类设计
本文详细介绍了 Qt 中的 QSettings 类,包括初始化、读取、写入和删除配置信息的操作。还讲解了在整个系统中怎么去设计系统配置文件读取类 我们还介绍了 QSettings 的应用场景。通过合理使用类CShortWaveConfig,您可以轻松管理和存储应用程序的配置信息,提高应用程序的灵活性和可维护性。原创 2024-07-04 22:20:51 · 1205 阅读 · 3 评论 -
STL中的迭代器模式:将算法与数据结构分离
STL 中的算法是一组函数模板,它们接受迭代器作为参数,并对迭代器范围内的元素执行操作。这些算法包括排序、搜索、复制、删除等操作。由于算法是独立于数据结构的,因此它们可以与任何支持迭代器接口的容器一起使用。通过将算法与容器分离,STL 允许程序员根据需要组合不同的算法和容器。例如,你可以使用排序算法对向量进行排序,或者使用搜索算法在集合中查找元素。这种灵活性使得 STL 能够适应各种不同的应用场景。总的来说,STL 的设计方式通过将算法与数据结构分离,实现了代码的可重用性、可维护性和灵活性。原创 2024-06-27 22:15:07 · 981 阅读 · 7 评论 -
Qt实现单例模式:Q_GLOBAL_STATIC和Q_GLOBAL_STATIC_WITH_ARGS
} \从上述代码可以看出:1)根据不同的 NAME,生成了不同的命名空间,虽然对象创建函数、多线程同步变量guard的名字一样,但是是在不同的命名空间,因此生成的QGlobalStatic也是不一样的,其实这个也是实现技巧。2)QBasicAtomicInt 是 原子操作,是线程安全的,它的介绍在这里就不在赘述了,不明白的地方请自行查阅。3)Q_GLOBAL_STATIC是Q_GLOBAL_STATIC_WITH_ARGS的特例。原创 2024-06-16 23:38:56 · 1128 阅读 · 13 评论 -
接口和抽象类:如何使用普通类模拟接口和抽象类
不同的编程语言对接口和抽象类的定义方式可能有差别,但差别并不会很大。因为Java既支持抽象类,又支持接口,所以我们使用Java进行举例讲解,以便读者对这两个有直观的认识。首先,我们看一下如何在 Java 中定义抽象类。下面这段代码是一个典型的抽象类使用场景(模板设计模式)。Logger 是一个记录日志抽象类,FileLogger 类和 MessageQueueLogger 类继承 Logger 类,分别实现不同的日志记式:将日志输出到文件中和将日志输出到消息队列中。原创 2024-06-16 11:54:56 · 975 阅读 · 4 评论 -
C++之对象封装
面向对象编程是一种非常广泛的编译方式,很多开发者可能对它是既了解又不了解。对一些基础的知识会用,但又不知道是否用得合适,能不能有一个标准来判定。其实这恰恰表明对面向对象编程还是掌握的不够深入。一切设计没有标准只有原则,这也意味着,实际场景下,在考虑原则的同时,更要考虑实际的需求进行适当的取舍。最好的设计方法是没有的,只有最合适的设计方法。原创 2024-06-05 22:21:28 · 881 阅读 · 10 评论 -
哪些代码看似面向对象编程风格,实则面向过程编程风格
还有一种在面向对象编程中常见的面向过程编程风格的代码:数据定义在一个类中,而方法定义在另一个类中。读者可能认为,这么明显的面向过程编程风格的代码,谁会这样写呢?实际上,如果读者基于 MVC三层结构进行 web项目的后端开发,那么这样的代码几乎天天都在写。传统的 MVC结构分为Model层、View层和Controller层。原创 2024-06-03 23:17:39 · 776 阅读 · 11 评论 -
Qt 插件机制使用及原理
Qt插件机制是一种强大且灵活的功能扩展方式,它允许开发者通过创建和加载插件来增强Qt应用程序的功能。通过遵循一定的规范,开发者可以轻松地创建和使用插件,从而满足各种复杂和多变的需求。原创 2024-05-29 23:44:45 · 1342 阅读 · 10 评论 -
基于接口而非实现编程:有没有必要为每个类都定义接口
这样的接口设计新没有意义了,不过,如果读者认为这种思考方式顺畅,那么可以接受, 但要注意,在将实现类中的方法搬移到接口定义中时,要有选择性地进行搬移,不要搬移与具体实现相关的方法,如AliyunImageStore类中的generateAccessToken()方法就不应该被搬移到接口中。上游系统面向接口而非实现编程,不依赖不稳定的实现细节,这样,当实现发生变化时,上游系统的代码基本不需要做改动,以此降低代码的耦合性,提高代码的扩。在本节最终重构之后的代码中,尽管我们通过接口隔离了两个具体的类现。原创 2024-05-28 23:33:41 · 719 阅读 · 9 评论 -
C++架构设计
设计模式是在软件开发中经常出现的问题的通用解决方案。使用设计模式可以帮助开发者编写可复用、可维护的代码。创建型模式(Creational Patterns)创建型模式关注于对象创建过程的优化和抽象。a. 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。这在需要控制资源访问或维护全局状态时非常有用。b. 工厂模式(Factory Pattern):通过一个工厂类来创建对象,而无需指定具体的类。这有助于实现代码解耦,降低依赖性。转载 2024-05-27 22:54:51 · 429 阅读 · 1 评论 -
解耦:哪些方法可以用来解耦代码
模块之间通过接口通信,模块之间的耦合度很小,每个小型团队负责一个独立的高内聚模块的开发,最终,将各个模块组合构成一个复杂的系统。从图5-1可以看出,中间层的引入简化了模块之间的依赖关系,让代码结构更加清晰。实际上,”高内聚、低耦合”是一种通用的设计思想,它不仅可以指导细粒度的类之向关系的设计,还能指导粗粒度的系统、架构、模块的设计。实际上,在平时的开发中,解耦到处可见,例如,Spring中的AOP能实现业务代码与非业务代码的解耦,IoC 能实现对象的创建和使用的解耦,除此之外,读者还能想到哪些解耦场景?原创 2024-05-24 19:55:08 · 1095 阅读 · 6 评论 -
单元测试:保证重构不出错的有效手段
单元测试由开发工程师而非测试工程师编写,用来测试代码的正确性。相比集成测试(integration testing),单元测试的粒度更小。集成测试是一种端到端(end to send,从请求到返回所涉及的代码执行的整个路径)的测试。集成测试的测试对象是整个系统或某个功能模块,如测试用户的注册、登录功能是否正常。而单元测试是代码层级的测试,其测试对象是类或函数,用来测试类或函数是否能够按照预期执行。下面结合代码示例介绍单元测试。...原创 2024-05-21 23:54:43 · 1337 阅读 · 19 评论 -
设计模式之享元模式
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,通过使用共享对象来支持大量的细粒度对象,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。在享元模式中,有些对象可以被多个客户端共享,以减少创建对象的数量。享元模式的核心在于享元工厂类,它负责创建和管理享元对象,并提供对外访问的接口。(1) 减少内存占用:享元模式通过共享相同或相似的对象,避免了大量相同对象的重复创建,从而显著降低了系统的内存占用。(2) 提高系统性能。原创 2024-05-20 22:21:49 · 1103 阅读 · 1 评论 -
重构四要素:目的、对象、时机和方法
一些软件工程师对为什么要重构(why)、到底重构什么(what)、什么时候重构(when)应该如何重构(how)等问题的理解不深,对重构没有系统行认识、在面对质量不佳的代码时,这些软件工程师没有足够的重构技巧,不能系统地进行重构、为了让读者对有清晰的认识,我们先来了解一下重构的目的、对象、时机和方法。原创 2024-05-13 21:46:01 · 746 阅读 · 20 评论 -
设计模式之访问者模式
扩展性:访问者模式使得在不修改已有类的情况下,可以轻松地增加新的操作。这符合开放-封闭原则(Open-Closed Principle),即对扩展开放,对修改封闭。分离操作与数据结构:访问者模式将操作从数据结构中分离出来,使得数据结构可以独立地变化,而无需修改相关的操作。这有助于减少代码的耦合度,提高系统的可维护性。灵活性:访问者模式允许操作以不同的方式实现,而不影响数据结构。这提供了更大的灵活性,可以根据需要选择不同的操作实现。双重分派。原创 2024-05-11 22:36:09 · 833 阅读 · 7 评论 -
面向对象编程与面向过程编程和函数式编程之间的区别
是现在流行的编程范式(编程风格)。。随着面向对象编程的出现,面向过程编程已经逐渐退出了历史舞台,函数式编程目前还没有被程序员广泛接受,只能作为面向对象编程的补充。为了更好地理解面向对象编程,我们在本节中补充讲解面向过程编程和函数式编程,并且将面向对象编程与面向过程编程和函数式编程进行对比。原创 2024-05-07 22:49:49 · 1051 阅读 · 8 评论 -
设计模式之外观模式
优点1)降低耦合度:即减少相互依赖,客户端与子系统之间的耦合度降低,客户端只与外观角色交互,不需要了解子系统的具体实现。2)简化操作:客户端不再需要了解子系统的内部实现和具体细节,只需要与外观角色交互,简化了客户端的操作。3)易于维护:当子系统内部发生变化时,只需要修改外观角色,而不需要修改客户端代码,降低了维护成本。缺点1)不符合“开闭原则”:如果新增子系统或删除子系统,可能需要修改外观角色的代码,这在一定程度上违反了“开闭原则”。原创 2024-05-05 22:51:03 · 1162 阅读 · 13 评论 -
如何进行面向对象分析、面向对象设计和面向对象编程
假设我们正在参与一个微服务的开发。微服务通过 HTTP 暴露接口给其他系统调用,换句话说,其他系统通过 URL调用微服务的接口。某天,项目管理者对我们说:“为了保证接口调用的安全性,需要设计和实现接口调用的鉴权功能,只有经过认证的系统,才能调用微服务的接口。希望你们负责这个任务,争取尽快上线这个功能。”这个时候,我们可能感到无从下手原因有下列两点。(1)需求不明确项目管理者提出的需求有些模糊和笼统,不够具体和细化,与落地进行设计和编码还有一定的距离。原创 2024-04-30 21:56:18 · 1385 阅读 · 9 评论 -
C++可变参数接口,批量写入和读取参数值的设计和实现
最近在做项目的时候,我们小组做的模块和另外一个小组做的模块的交付通过动态库接口的方式,他们有一个接口是这样的定义的:name是参数名称,data为序列化的字节数据,小端对齐,数据类型包括一般数据类型int、long、double等;复杂数据类型包括原生数组、结构体、类等。例如:单个参数的配置和读取都很简单,利用之前章节介绍的序列化类,参数配置可以这样写:参数1(int)的配置代码如下:参数2(bool)的配置代码如下:参数3(double)的配置代码如下:参数4(int[10])的配原创 2024-04-29 00:03:48 · 807 阅读 · 5 评论 -
MYQSL基于C++的数据库连接池设计与实现
数据库连接池可提前把多个数据库连接建立起来,然后把它放到一个池子里边,就是放到一个容器里边进行维护。这样的话就能够避免数据库连接的频繁的创建和销毁,从而提高程序的效率。线程池其实也是同样的思路,也是为了避免线程的重复的创建和销毁。这个图模拟的是一个网络通信,在左侧有多个客户端,客户端给服务器发数据,发数据可以理解为就是发送一个请求,比如说请求登录,请求注册,请求下载或者上传某些文件。我们还需要做身份的验证,或者说做数据的读和写操作,那这个数据在哪里呢?原创 2024-04-27 09:05:27 · 849 阅读 · 6 评论 -
组合优于继承:什么情况下可以使用继承?
面向对象编程中有一条经典的设计原则:组合优于继承,也常被描述为多用组合,少用继承。为什么不推荐使用继承?相比继承,组合有哪些优势?如何决定是使用组合还是使用继承?本节围绕这3个问题详细讲解这条设计原则。原创 2024-04-25 23:25:47 · 1018 阅读 · 6 评论 -
设计模式之原型模式
原型模式的优点:便于通过克隆方式创建复杂对象、也可以避免重复做初始化操作.不需要与类中所属的其他类耦合等。如果对象中包括了循环引用的克隆,以及类中深度使用对象的克隆,都会使此模式变得异常麻烦。综上所述,原型设计模式在特定场景下具有显著的优势,但也需要注意其潜在的缺点和限制。在选择是否使用原型设计模式时,需要根据具体的应用场景和需求进行权衡。原创 2024-04-23 22:03:12 · 1397 阅读 · 9 评论 -
设计模式之责任链模式(二): 实现方式
尽管我们给出了典型的职责链模式的代码实现,但在实际的开发中,我们还是要具体问题具体对待,因为职责链模式的代码实现会根据需求的不同而有所变化。实际上,这一点对于有设计模式都适用。原创 2024-04-23 13:02:05 · 1373 阅读 · 3 评论 -
编程技巧:小技巧,大作用,一招提高代码的可读性
拆分之后的函数的职责明确。根据作者的经验,函数的参数一般超过5个就算过多了,因为函数参数超过5个之后,在调用函数时,调用语句容易超出一行代码的长度,要将其分为两行甚至多行,导致代码的可读性降低。在编写代码时,我们要有模块化思维,善于将大块的复杂的代码封装成类或函数,让阅读代码的人不会迷失在代码的细节中,这样能极大地提高代码的可读性。如果导致函数的参数过多的原因是函数的职责不单一,那么我们可以通过将这个函数拆分成多个函数的方式来减少参数。4)我们可以将部分嵌套代码封装成函数,以减少嵌套层数,示例代码如下。原创 2024-04-17 22:38:27 · 939 阅读 · 10 评论 -
LoD:如何实现代码的“高内聚、低耦合“
单从"LoD"这个名字来看,我们完全猜不出这条设计原则讲的是什么。其实,LoD还可以称为“最少知识原则”(The Least Knowledge Principle)。“最少知识原则”的英文描述是:“Each unit should have only limited knowledge about other units;原创 2024-04-16 20:22:48 · 1057 阅读 · 3 评论 -
DRY 原则:相同的两段代码就一定违反 DRY 原则吗?
DRY 原则(Don't Repeat Youself)翻译成中文是:不要编写重复的代码。很多人对其中的“重复”二字有误解,认为项目中存在两段相同的代码就是重复,实际上,相同的两段代码未必违反 DRY原则,相反,不同的两段代码也未必就不违反DRY 原则。本节我们就重点来讲一下怎么才算是“重复”。原创 2024-04-12 20:50:54 · 783 阅读 · 0 评论 -
KISS 原则和 YAGNI原则
KISS原则的英文描述有3种版本:Keep It Simple and Supid、 keep It Short and Simple、Keep It Simple and Straightforward。其实,它们要表达的意思差不多,即“尽量保持简单”。KISS原则是一个“万金油”一样的设计原则,可以应用在诸多场合。它不仅经常用来指导软件开发,还经常用来指导系统设计、产品设计等,如冰箱、建筑和手机的设计等,本书讲解的是代码设计,因此,接下来,我们重点讲解如何在程序开发中应用KISS 原则。原创 2024-04-10 21:57:51 · 1139 阅读 · 0 评论 -
编程大牛坚持了 10 年的 10 个编程好习惯
之所以要写注释,是因为当你在写某个程序的时候,可能当下记得很清楚,这一段是什么机制、如何实现,但是当你写的程序越来越多,你会忘记当初为什么这样写,改动和交接也十分麻烦,对代码进行注释就可以有效避免这种情况。编写官方文档的人,也通常就是这些技术或者软件的开发者,他们是对这些东西最了解的人,所以编写的文档不仅质量非常高,通常内容也都是最新的。了解开源项目:许多优秀的软件项目都是开源的,通过阅读这些项目的源代码,你可以更深入地了解它们的工作原理、架构设计和实现细节。写一天代码,70%的时间都放到重构上都不过份。原创 2024-04-05 22:46:04 · 770 阅读 · 6 评论 -
面向对象设计之开闭原则
开闭原则(Open Closed Principle,OCP),又称为“对扩展开发、对修改关闭”原则。开闭原则既是 SOLID 原则中最难理解、最难掌握的,又是最有用的。之所以说开闭原则难理解,是因为“怎样的代码改动才被定义为'扩展’?怎样的代码改动才被定义为'修改’?怎么才算满足或违反'开闭原则’?修改代码就一定意味着违反'开闭原则’吗?”等问题都比较难理解。之所以说开闭原则难掌握,是因为“如何做到'对扩展开发、对修改关闭’?如何在项目中灵活应用'开闭原则’,避免在追求高扩展性的同时影响代码的可读性?”等原创 2024-04-01 21:25:09 · 729 阅读 · 1 评论 -
如何避免过度设计
总之,避免过度设计需要保持清晰的目标、关注用户需求、简化设计、避免过早优化,并持续学习和改进。通过遵循这些原则和建议,你可以有效地避免过度设计,提高项目的成功率和效率。原创 2024-03-29 11:04:58 · 1323 阅读 · 6 评论 -
如何写出高质量代码
想要写出满足上述代码质量评价标准的高质量代码,我们需要掌握一些细化、可落地的编程方法论,包括面向对象设计范式、设计原则、代码规范、重构技巧和设计模式等。而掌握这些编程方法论的最终目的是编写出高质量的代码。这些编程方法论是后续讲解的重点内容,我们先熟悉一下它们。原创 2024-03-27 22:51:53 · 1068 阅读 · 17 评论 -
如何评价代码质量
在评价代码质量时,可以使用静态代码分析工具来自动检查代码中的潜在问题,如语法错误、未使用的变量、潜在的空指针异常等。此外,代码审查也是一个重要的环节,通过团队成员的互相审查可以发现潜在的问题和改进点。最终,代码质量的评价是一个主观与客观相结合的过程,需要综合考虑上述多个方面,并根据项目的具体需求和团队的实际情况进行判断和评估。原创 2024-03-25 23:08:14 · 748 阅读 · 11 评论 -
设计模式之状态模式(一)
优点清晰的结构和逻辑:状态机模式使得对象的行为与其状态紧密相关,使得代码结构更加清晰,逻辑更加明确。每个状态及其转换都被明确地定义和封装,使得程序易于理解和维护。扩展性好:当需要添加新的状态或修改现有状态的行为时,只需要添加新的状态类或者修改现有状态类的实现,而不需要修改上下文或其他状态类的代码。这降低了代码的耦合度,提高了系统的可扩展性。减少条件分支:状态机模式通过将状态转换逻辑封装在状态类中,减少了在上下文中使用大量的条件分支(如if-else或switch-case)的情况。原创 2024-03-24 13:17:48 · 1153 阅读 · 7 评论 -
面向对象设计之单一职责原则
单一职责原则(Single Responsibility Principle,SRP)的描述:一个类或模块只负责完一个职责(或功能)(A class or module should have a single reponsibility)。注意,单一职责原则描述的对象有两个:类(class)和模块(module)。关于这两个概念我们有两种理解方式。一种理解方式是把模块看作比类更加抽象的概念,把类看作一种模块;另一种理解方式是把模块看作比类更粗粒度的代码块,多个类组成一个块。原创 2024-03-19 22:54:46 · 1319 阅读 · 4 评论 -
面向对象设计之依赖反转原则
依赖反转是面向对象设计的基本原则之一。这个原则强调高层模块不应该依赖于低层模块,它们都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象。这有助于降低模块间的耦合度,提高系统的可维护性和可扩展性。1.接口和抽象类:通过定义接口或抽象类来隐藏具体实现细节,高层模块依赖于这些接口或抽象类,而不是具体的实现类。这样,当需要更换底层实现时,只需要修改接口或抽象类的实现,而不需要修改高层模块的代码。2.依赖注入:通过构造函数、setter方法或接口注入等方式,将依赖的对象传递给需要它的对象。原创 2024-03-12 22:02:40 · 1045 阅读 · 13 评论 -
面向对象设计之里氏替换原则
里氏替换原则(Liskov Substitution principle)是由芭芭拉·利斯科夫(Barbara Liskov)在1987年在一次会议上名为“数据的抽象与层次”的演说中首先提出。他当时是这样描述这条原则的:如果S是T的子类型,那么T的对象可以被S的对象所替换,并不影响代码的运行。1966年,Robert Martin在他的SOLID原则中重新描述了里氏替换原则:使用父类对象的函数可以在不了解子类的情况下替换为使用子类对象。原创 2024-03-10 17:20:34 · 1198 阅读 · 15 评论 -
设计模式之中介者模式
优点1.简化对象交互:中介者模式通过引入中介者对象,将原本多个对象之间的复杂交互关系转化为中介者与对象之间的一对多交互,从而简化了对象之间的交互关系。这使得原本网状结构的交互关系变为星型结构,使得代码更易于理解和维护。2.降低耦合度:通过中介者模式,对象之间的直接依赖关系被转化为对中介者的依赖,从而降低了对象之间的耦合度。这使得对象更易于独立地改变和复用,符合面向对象设计的“开闭原则”。3.集中控制:中介者模式将多个对象之间的交互行为集中到一个中介者对象中,使得这些行为的控制和管理更加集中和方便。原创 2024-03-10 13:40:17 · 1312 阅读 · 6 评论 -
设计模式之模板方法模式
优点1.代码复用:模板方法模式允许你定义一个算法的基本步骤,并且允许子类在不改变算法结构的情况下重定义某些步骤。这样可以避免子类代码中重复的代码,提高了代码的复用性。2.封装不变部分:模板方法模式封装了算法的不变部分,使得算法的核心逻辑得到保护不会被错误地修改。3.扩展性:由于算法的核心逻辑已经被封装在模板方法中,因此当需要增加新的步骤或者修改某些步骤时,只需要在相应的子类中实现或修改对应的方法,而不需要修改模板方法,具有良好的扩展性。原创 2024-03-08 13:12:30 · 1498 阅读 · 14 评论 -
设计模式之代理模式
优点1.解耦:代理模式能够解耦客户端和目标对象之间的直接交互,客户端只需要与代理对象交互,而个需要知道自标对象的体实现这有助于降低系统的耦合度,使得系统更加灵活和可扩展。2.增加额外的处理逻辑:代理对象可以在将请求传递给目标对象之前或之后:添加额外的处理逻辑。这可以用于实现一些特殊的功能,如访问控制、缓存、日志记录等3.保护目标对象:代理模式可以保护目标对象,避免其被直接访问或暴露。这可以防证目标对象被恶意访问或修改,提高系统的安全性。缺点。原创 2024-03-07 09:36:44 · 1084 阅读 · 16 评论