当前位置: 首页 > news >正文

【设计模式】02-SOLID 设计原则

面向对象编程(OOP)是一种广泛应用的编程范式,它鼓励开发者通过对象来模拟现实世界。为了提高面向对象设计(OOD)的质量和可维护性,Robert C. Martin提出了 SOLID 原则,这五个原则构成了编写良好、可扩展和可维护OOP代码的基础。

SOLID是一个缩写词,代表以下设计原则(及其缩写):

  • Single Responsibility Principle (SRP)
  • Open-Closed Principle (OCP)
  • Liskov Substitution Principle (LSP)
  • Interface Segregation Principle (ISP)
  • Dependency Inversion Principle (DIP)

这五个特定的主题贯穿了对模式和软件设计的一般讨论,所以在我们深入研究设计模式之前(我知道你们都很渴望),我们将简要回顾一下SOLID原则是什么。

2.1 S - 单一职责原则(Single Responsibility Principle)

每个类应该只有一个改变的理由,即一个类应该只负责一个功能领域中的相应职责。这有助于使类更加可维护,并减少在代码需要变更时出现的复杂性。

C++ 示例

class Logger {
public:void logToFile(const std::string& message) {// 将消息记录到文件}
};class Order {// Order类的其他职责...Logger logger;public:void finalizeOrder() {// 完成订单处理logger.logToFile("Order finalized.");}
};

在上述示例中,Logger类负责日志记录的职责,而Order类处理订单相关的业务逻辑,并使用Logger来记录日志,而不是自己处理日志逻辑。

2.2 O - 开放/封闭原则(Open/Closed Principle)

软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。这意味着应该能够在不修改现有代码的情况下增加新功能。

C++ 示例

class Shape {
public:virtual double area() const = 0;
};class Rectangle : public Shape {double width, height;public:double area() const override {return width * height;}
};class Circle : public Shape {double radius;public:double area() const override {return 3.14159 * radius * radius;}
};

这里,Shape是一个抽象基类,它允许派生类通过实现area方法来扩展,而无需修改基类或其他派生类。

2.3 L - 里氏替换原则(Liskov Substitution Principle)

子类型必须能够替换掉它们的基类型。这意味着如果程序中使用了基类的对象,那么可以无缝地使用其子类的对象替换,而不会影响程序的正确性。

C++ 示例

void printArea(const Shape& shape) {std::cout << shape.area() << std::endl;
}// 由于Rectangle和Circle都是Shape的子类,
// 它们的对象都可以传递给printArea函数。
Rectangle rect;
Circle circle;
printArea(rect);
printArea(circle);

在这个例子中,不管是Rectangle还是Circle对象,都可以传递给printArea函数,因为它们都遵循Shape的约定。

2.4 I - 接口隔离原则(Interface Segregation Principle)

客户端不应该被迫依赖于它们不使用的方法。接口隔离原则鼓励我们创建细粒度的接口,这样客户端只需要了解它们真正使用的方法。

C++ 示例

class Printer {
public:virtual void printDocument(const Document& doc) = 0;
};class Scanner {
public:virtual void scanDocument(Document& doc) = 0;
};// 不应该强迫一个只打印机实现扫描方法,
// 或者一个只扫描仪实现打印方法。
class OfficePrinter : public Printer, public Scanner {void printDocument(const Document& doc) override {// 实现打印}void scanDocument(Document& doc) override {// 实现扫描}
};

在这里,OfficePrinter实现了Printer

Scanner接口,但如果有一个只需要打印功能的类,它就只实现Printer接口。

2.5 D - 依赖倒置原则(Dependency Inversion Principle)

高层模块不应该依赖低层模块,两者都应该依赖抽象。抽象不应该依赖细节,细节应该依赖抽象。这意味着我们应该针对接口编程,而不是针对实现编程。

C++ 示例

class DataAccess {
public:virtual Data getData() = 0;
};class FileDataAccess : public DataAccess {Data getData() override {// 从文件系统获取数据}
};class Application {DataAccess& dataAccess;public:Application(DataAccess& da) : dataAccess(da) {}void doWork() {Data data = dataAccess.getData();// 使用数据}
};FileDataAccess fileDataAccess;
Application app(fileDataAccess);
app.doWork();

这里的Application依赖于DataAccess抽象,而不是具体的FileDataAccess,使得数据访问的具体实现可以灵活更换。

SOLID原则为面向对象设计提供了强大的指导,遵循这些原则将帮助你构建更健壮、灵活且易于维护的软件系统。在C++编程中运用这些原则,能够使你的代码质量大幅提升。

相关文章:

【设计模式】02-SOLID 设计原则

面向对象编程&#xff08;OOP&#xff09;是一种广泛应用的编程范式&#xff0c;它鼓励开发者通过对象来模拟现实世界。为了提高面向对象设计&#xff08;OOD&#xff09;的质量和可维护性&#xff0c;Robert C. Martin提出了 SOLID 原则&#xff0c;这五个原则构成了编写良好、…...

突然间我懂了软件

什么是 “遗留代码” – 它是一个不再由具有这些代码相关理论的人维护的代码库。 单枪匹马的工程师能做出比同样有能力的专业团队更好的产品。单干的工程师会花时间为自己的程序建立一套完整的理论&#xff0c;而专业人员则会定期在不同的项目之间流动&#xff0c;他们只对自己…...

游戏美术的技与艺

大家好&#xff0c;我是阿赵。   可能很多朋友都知道&#xff0c;我刚进入游戏行业的时候&#xff0c;做的是美术工作&#xff0c;包括了建模、贴图、动画等&#xff0c;都做过。我对各种美术资源制作也都很熟悉&#xff0c;懂得很多制作的技术。但最后&#xff0c;我却没有继…...

Python(35):Python3 通过https上传文件和下载文件

Python(35):Python3 通过https上传文件和下载文件 Python http方式的下载&#xff0c;参考&#xff1a;https://blog.csdn.net/fen_fen/article/details/113753983 https需要先安装需要的模块 1、上传示例 1.1、调用&#xff1a; upload_strategy(access_token,"1234…...

【MySQL】日期格式为 YYYY-MM 无法直接使用 DATE_SUB 函数的解决方案(特殊处理 或 PERIOD_DIFF 函数)

力扣题 1、题目地址 1843. 可疑银行账户 2、模拟表 表&#xff1a;Accounts Column NameTypeaccount_idintmax_incomeint account_id 是这张表具有唯一值的列。每行包含一个银行账户每月最大收入的信息。 表&#xff1a;Transactions Column NameTypetransaction_idint…...

Redis的key淘汰方式和内存不足淘汰方式

Redis的key过期淘汰方式 Redis key过期策略 定期删除惰性删除 Redis如何淘汰过期的key 定期删除 隔一段时间&#xff0c;就随机抽取一些设置了过期时间的key&#xff0c;检查其是否过期&#xff0c;如果过期就删除定期删除可能会导致很多过期key到了时间并没有被删除掉&#x…...

java使用redis

1、pom.xml文件里面增加如下依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2、yml文件增加如下配置&#xff1a; redis:host: loc…...

MySQL技能树

MySQL作为一款广泛使用的关系型数据库管理系统&#xff0c;提供了丰富多样的SQL语句以支持数据的创建、查询、更新和删除等操作。以下是一份MySQL语句操作大全的概览&#xff0c;涵盖从数据库管理到复杂查询的常用命令&#xff1a; ### 一、数据库管理&#xff08;DDL - 数据定…...

redis获取过期时间

03&#xff0c;redisTemplate_redistemplate 获取剩余时间-CSDN博客 11.返回当前key所对应的剩余过期时间 redisTemplate.getExpire(key);1 12.返回剩余过期时间并且指定时间单位 redisTemplate.getExpire(key, unit);...

ERROR in Plugin “react“ was conflicted .... 天坑留念-turborepo、eslint plugin

前两天项目代码拉下来&#xff0c;装完依赖启动的时候直接报错&#xff1a; [eslint] Plugin "react" was conflicted between ".eslintrc.js eslint-config-custom eslint-config-alloy/react" and "BaseConfig D:\pan\erp\test\business-servic…...

MergeTwoSortedLists 【合并有序链表】

有种归并排序的感觉 链表好久不用有些生疏了&#xff0c;思想思路是对的&#xff0c;但是代码写出来有问题&#xff0c;。 写完说点感受&#xff1a; 当时在学校学习链表的时候&#xff0c;就了解到链表分为“有头节点”和“无头节点”的链表&#xff0c;所以这里好像就不练&am…...

基于多反应堆的高并发服务器【C/C++/Reactor】(中)HttpRequest模块 解析http请求协议

一、HTTP响应报文格式 HTTP/1.1 200 OK Bdpagetype: 1 Bdqid: 0xf3c9743300024ee4 Cache-Control: private Connection: keep-alive Content-Encoding: gzip Content-Type: text/html;charsetutf-8 Date: Fri, 26 Feb 2021 08:44:35 GMT Expires: Fri, 26 Feb 2021 08:44:35 GM…...

muduo网络库剖析——网络地址InetAddress类

muduo网络库剖析——网络地址InetAddress类 前情从muduo到my_muduo 概要socketaddr_in介绍成员用法 网络地址转换函数 框架与细节成员函数使用方法 源码结尾 前情 从muduo到my_muduo 作为一个宏大的、功能健全的muduo库&#xff0c;考虑的肯定是众多情况是否可以高效满足&…...

什么是本地IP?服务器本地IP有哪些优势?

本地IP是指直接在互联网上分配给服务器或设备的IP地址&#xff0c;而不是通过NAT&#xff08;网络地址转换&#xff09;或 代理等中间设备进行转发。让我们关注本地IP的优势。 1.直接访问&#xff1a;原始IP允许无中间设备转发或代理直接访问服务器或设备。这减少了网络延迟&a…...

Open CASCADE学习|参数化球面的奇异性

参数曲面的奇异性是一个相对复杂的概念&#xff0c;它涉及到参数曲面的几何特性和参数化过程中的一些特殊情况。参数曲面通常用于描述三维空间中的复杂形状&#xff0c;通过参数方程将二维参数域映射到三维空间中。然而&#xff0c;在某些情况下&#xff0c;参数曲面可能会表现…...

基础知识篇(一)Acticity生命周期

Activity 类是 Android 应用的关键组件&#xff0c;而 activity 的启动和组合方式是平台应用模型的基本组成部分。与使用 main() 方法启动应用的编程范式不同&#xff0c;Android 系统会通过调用与其生命周期特定阶段对应的特定回调方法&#xff0c;在 Activity 实例中启动代码…...

Java内存结构

前文&#xff1a; 《Java8之类的加载》 《Java8之类加载机制class源码分析》 写在开头&#xff1a;本文为学习后的总结&#xff0c;可能有不到位的地方&#xff0c;错误的地方&#xff0c;欢迎各位指正。 JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数…...

Java--ListUtil工具类,实现将一个大列表,拆分成指定长度的子列表

文章目录 前言实现代码执行结果 前言 在项目中有时会出现列表很大&#xff0c;无法一次性批量操作&#xff0c;我们需要将列表分成指定大小的几个子列表&#xff0c;一份一份进行操作&#xff0c;本文提供这样的工具类实现这个需求。 实现代码 以下为ListUtil工具类代码实现…...

SpringSecurity 密码加密登录

SpringSecurity 密码加密登录 1.前端所需文件2.后端所用工具类3.登录代码4.灵魂一问 1.前端所需文件 import JSEncrypt from jsencrypt/bin/jsencrypt.min// 密钥对生成 http://web.chacuo.net/netrsakeypairconst publicKey MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqz…...

大模型实战作业03

大模型实战作业03 注&#xff1a; 因为微调数据较少&#xff0c;没有显示出个人助手的名字...

【AI视野·今日Sound 声学论文速览 第四十四期】Tue, 9 Jan 2024

AI视野今日CS.Sound 声学论文速览 Tue, 9 Jan 2024 Totally 27 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers DJCM: A Deep Joint Cascade Model for Singing Voice Separation and Vocal Pitch Estimation Authors Haojie Wei, Xueke Cao, Wenbo Xu…...

Windows Copilot 更新及使用教程

Windows Copilot 是一款由微软开发的人工智能辅助工具&#xff0c;可以通过学习用户的操作习惯和上下文&#xff0c;自动完成代码编写和其他重复性任务。它可以帮助开发人员提高工作效率&#xff0c;减少重复劳动。 以下是关于Windows Copilot的更新和使用教程的一些信息&…...

【Android开发】不同Activity之间的数据回传实例(一)摘桃子游戏

一、功能介绍 该项目实现的功能主要有&#xff1a; 在首页显示一个按钮点击该按钮跳转到桃园页面在桃园页面&#xff0c;点击桃子会弹窗显示摘到几个桃子&#xff0c;同时被点击桃子消失&#xff0c;总桃子数1点击退出桃园会返回首页&#xff0c;首页桃子数会根据点击的桃子数…...

增量式PID和脉冲轴组合控制阀门开度(算法介绍)

这篇博客我们以S7-1200PLC平台来举例,介绍我们的PID闭环控制器如何控制脉冲轴实现阀门角度控制。SMART PLC PID控制器控制伺服驱动器实现关节角度控制详细内容请参考下面文章: https://rxxw-control.blog.csdn.net/article/details/129658364https://rxxw-control.blog.csdn…...

解决Vue.js Devtools未检测到Vue实例的问题

解决Vue.js Devtools未检测到Vue实例的问题 解决Vue.js Devtools未检测到Vue实例的问题1. 确保Vue.js已正确加载1.1 在HTML文件中直接引入1.2 在构建工具&#xff08;如Webpack&#xff09;中配置引入1.3 检查与验证 2. 检查Vue.js Devtools扩展安装状态2.1 打开Chrome浏览器扩…...

【Java基础】进程与线程,并发与并行,CPU单核与多核

目录 1 进程与线程2 CPU单核与多核 1 进程与线程 进程与线程基本单位的对象不同 进程是操作系统进行资源分配&#xff08;包括cpu、内存、磁盘IO等&#xff09;的最小单位线程是CPU调度和分配的基本单位 CPU看不到进程&#xff0c;只能看到待分配的一些线程 并发与并行 并发&…...

git修改最新提交(commit)信息

一、修改最近一次commit信息 1、首先通过git log查看commit信息 2、使用命令git commit --amend进入命令命令模式&#xff0c;按i进入编辑模式&#xff0c;修改好commit信息后按Esc键退出编辑模式&#xff0c;然后输入:wq保存编辑信息&#xff08;注意使用英文输入法&#xf…...

想寻找Axure的替代品?我们已经试用了10+款设计工具,来看看吧!

Axure是许多产品经理和设计师进入快速原型设计的首选工具&#xff0c;但Axure的使用成本相对较高&#xff0c;学习曲线陡峭&#xff0c;许多设计师正在寻找可以取代Axure的原型设计工具&#xff0c;虽然现在有很多可选的设计工具&#xff0c;但质量不均匀&#xff0c;可以取代A…...

报文大小限制、请求体类型总结

文章目录 1. 各节点请求体有无限制1.1 http协议1.2 TCP/IP层限制1.3 浏览器1.4 nginx1.5 gateway1.6 tomcat1.7 springboot1.8 内存、磁盘处理不了一切白搭 2. 请求体类型2.1 application/x-www-form-urlencoded2.2 multipart/form-data2.3 application/json2.4 text/plain2.5 …...

rknn加载onnx时报错 GLIBC=2.29 no found librknnc.so

rknn 中onnx转rknn在虚拟机中运行时发现报错. GLIBC2.29 no found /****/librknnc.so 昨天还正常的, 今天装了个ftp 和宝塔面板就出错了. 我估计根据报错地址, 找到了librknnc.so文件, 权限也给了777仍然不行 , 我怀疑是GLIBC的版本不对 ,网上给的方法是下载源码, 然后自己手动…...