【C++设计模式】单一职责原则
2023年8月26日,周六上午
目录
- 概述
- 一个简单的例子
- 用单一职责原则来设计一个简单的学生管理系统
概述
单一职责原则(Single Responsibility Principle,SRP),它是面向对象设计中的一个基本原则。
单一职责原则的核心思想是,一个类应该只有一个引起它变化的原因。
换句话说,一个类应该只负责一项功能或职责。
这样做的好处是,当需求发生变化时,只有与该功能相关的类需要进行修改,而不会影响其他不相关的功能。
一个简单的例子
class FileManager {
public:void readFile(std::string filename) {// 读取文件的代码逻辑}void writeFile(std::string filename) {// 写入文件的代码逻辑}void deleteFile(std::string filename) {// 删除文件的代码逻辑}void encryptFile(std::string filename) {// 加密文件的代码逻辑}void compressFile(std::string filename) {// 压缩文件的代码逻辑}
};
在这个示例中,FileManager类负责文件的读取、写入、删除、加密和压缩等操作。
这个类违反了单一职责原则,因为它承担了多个不同的功能,即文件操作和文件处理。
为了遵循单一职责原则,我们可以将文件操作和文件处理分离为两个独立的类:
class FileManager {
public:void readFile(std::string filename) {// 读取文件的代码逻辑}void writeFile(std::string filename) {// 写入文件的代码逻辑}void deleteFile(std::string filename) {// 删除文件的代码逻辑}
};class FileProcessor {
public:void encryptFile(std::string filename) {// 加密文件的代码逻辑}void compressFile(std::string filename) {// 压缩文件的代码逻辑}
};
现在,FileManager类负责文件的基本操作,而FileProcessor类负责对文件进行加密和压缩等处理操作。这样,每个类都只有一个单一的职责,使得代码更加清晰、可维护和可扩展。
总结来说,单一职责原则要求将不同的职责分离到不同的类中,以确保每个类只负责一项功能。这样可以提高代码的可读性、可维护性和可扩展性,减少代码之间的耦合。
用单一职责原则来设计一个简单的学生管理系统
使用单一职责原则来设计一个简单的学生管理系统,可以将功能分解为以下几个类:
- Student类:表示学生对象,包含学生的基本信息(如姓名、学号、年龄)以及相关操作(如获取学生信息、修改学生信息)。
- StudentDatabase类:负责学生信息的存储和管理,包含增加学生、删除学生、查找学生等操作。
- StudentUI类:负责与用户交互,显示菜单选项,接收用户输入,并调用StudentDatabase类中的方法来执行相应的操作。
#include <iostream>
#include <vector>
#include <string>class Student {
private:std::string name;int studentId;int age;public:Student(std::string name, int studentId, int age): name(name), studentId(studentId), age(age) {}std::string getName() const {return name;}int getStudentId() const {return studentId;}int getAge() const {return age;}void updateName(std::string newName) {name = newName;}void updateAge(int newAge) {age = newAge;}
};class StudentDatabase {
private:std::vector<Student> students;public:void addStudent(const Student& student) {students.push_back(student);}void removeStudent(int studentId) {for (auto it = students.begin(); it != students.end(); ++it) {if (it->getStudentId() == studentId) {students.erase(it);break;}}}Student findStudent(int studentId) const {for (const auto& student : students) {if (student.getStudentId() == studentId) {return student;}}// 如果找不到对应的学生,则返回一个空的Student对象return Student("", -1, -1);}std::vector<Student> getAllStudents() const {return students;}
};class StudentUI {
private:StudentDatabase studentDB;public:void displayMenu() {std::cout << "=== 学生管理系统 ===" << std::endl;std::cout << "1. 添加学生" << std::endl;std::cout << "2. 删除学生" << std::endl;std::cout << "3. 查找学生" << std::endl;std::cout << "4. 显示所有学生" << std::endl;std::cout << "0. 退出" << std::endl;}void addStudent() {std::string name;int studentId, age;std::cout << "请输入学生姓名: ";std::cin >> name;std::cout << "请输入学生学号: ";std::cin >> studentId;std::cout << "请输入学生年龄: ";std::cin >> age;Student student(name, studentId, age);studentDB.addStudent(student);std::cout << "成功添加学生!" << std::endl;}void removeStudent() {int studentId;std::cout << "请输入要删除的学生学号: ";std::cin >> studentId;studentDB.removeStudent(studentId);std::cout << "成功删除学生!" << std::endl;}void findStudent() {int studentId;std::cout << "请输入要查找的学生学号: ";std::cin >> studentId;Student student = studentDB.findStudent(studentId);if (student.getStudentId() != -1) {std::cout << "找到学生: " << student.getName() << std::endl;std::cout << "学号: " << student.getStudentId() << std::endl;std::cout << "年龄: " << student.getAge() << std::endl;} else {std::cout << "未找到该学生!" << std::endl;}}void displayAllStudents() {std::vector<Student> students = studentDB.getAllStudents();if (students.empty()) {std::cout << "暂无学生信息!" << std::endl;} else {std::cout << "所有学生信息:" << std::endl;for (const auto& student : students) {std::cout << "姓名: " << student.getName() << ", ";std::cout << "学号: " << student.getStudentId() << ", ";std::cout << "年龄: " << student.getAge() << std::endl;}}}void run() {int choice;do {displayMenu();std::cout << "请输入选项: ";std::cin >> choice;switch (choice) {case 1:addStudent();break;case 2:removeStudent();break;case 3:findStudent();break;case 4:displayAllStudents();break;case 0:std::cout << "退出程序!" << std::endl;break;default:std::cout << "无效的选项,请重新输入!" << std::endl;}} while (choice != 0);}
};int main() {StudentUI studentUI;studentUI.run();return 0;
}
相关文章:
【C++设计模式】单一职责原则
2023年8月26日,周六上午 目录 概述一个简单的例子用单一职责原则来设计一个简单的学生管理系统 概述 单一职责原则(Single Responsibility Principle,SRP),它是面向对象设计中的一个基本原则。 单一职责原则的核心思…...
Windows docker desktop 基于HyperV的镜像文件迁移到D盘
Docker desktop的HyperV镜像文件,默认是在C盘下 C:\ProgramData\DockerDesktop\vm-data\DockerDesktop.vhdx如果部署的软件较多,文件较大,或者产生日志,甚至数据等,这将会使此文件越来越大,容易导致C盘空间…...
LM-INFINITE: SIMPLE ON-THE-FLY LENGTH GENERALIZATION FOR LARGE LANGUAGE MODELS
本文是LLM系列文章,针对《LM-INFINITE: SIMPLE ON-THE-FLY LENGTH GENERALIZATION FOR LARGE LANGUAGE MODELS》的翻译。 LM-INFiNITE:大语言模型的一个简单长度上推广 摘要1 引言2 相关工作3 LLMs中OOD因素的诊断4 LM-INFINITE5 评估6 结论和未来工作 …...
ShardingSphere——压测实战
摘要 Apache ShardingSphere 关注于全链路压测场景下,数据库层面的解决方案。 将压测数据自动路由至用户指定的数据库,是 Apache ShardingSphere 影子库模块的主要设计目标。 一、压测背景 在基于微服务的分布式应用架构下,业务需要多个服…...
二分图-染色法-dfs
1.判断一个图是否是二分图当且仅当图中不包含奇数环 2. dfs当前边为1 他的临边为2 看是否满足条件 3. 注意图有可能不是连通图 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays;public class BinaryG…...
SQL优化案例教程0基础(小白必看)
前提准备:本案例准备了100W的数据进行SQL性能测试,数据库采用的是MySQL, 总共介绍了常见的14种SQL优化方式,每一种优化方式都进行了实打实的测试, 逐行讲解,通俗易懂! 一、前提准备 提前准备一…...
webpack(一)模块化
模块化演变过程 阶段一:基于文件的划分模块方式 概念:将每个功能和相关数据状态分别放在单独的文件里 约定每一个文件就是一个单独的模块,使用每个模块,直接调用这个模块的成员 缺点:所有的成员都可以在模块外被访问和…...
基于Java+SpringBoot+Vue前后端分离人力资源管理系统设计和实现
博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…...
安装配置mariadb
记录下安装配置mariadb的经历。 环境:ubuntu22 一、apt在线安装 apt代理配置 APT是Ubuntu系统中用于安装和升级软件包的工具,如果本地没有可用的软件包,APT将会连接到远程软件包服务器下载软件包。在某些情况下,用户需要将APT的…...
Ant Design Vue 日期选择器DatePicker传给后台日期参数格式问题
花了一个下午才解决,官方组件文档里面是没有处理方案说明的。 项目版本:Ant Design Vue 2.0.2 前端部分代码: <template><a-modal:visible"visible":width"windowWidth":height"800":title"tit…...
springboot1.5.12升级至2.6.15
首先,加入springboot升级大版本依赖,会在升级过程中打印出错日志提示(升级完毕可去除) <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-properties-migrator</art…...
Android Event事件分发(新版本)
之前写过一个方案(添加链接描述),突然觉得很麻烦,于是有了新的方案: 首先先说要解决的问题: 当父布局能滑动,子View也能滑动,就会出现滑动冲突 解决思路:我们按下子Vie…...
可控生成:ControlNet原理
🤗关注公众号funNLPer体验更佳阅读🤗 论文:Adding Conditional Control to Text-to-Image Diffusion Models 代码:lllyasviel/ControlNet 简单来说ControlNet希望通过输入额外条件来控制大型图像生成模型,使得图像生成模型根据可控。 文章目录 1. 动机2. ControlNet原理…...
【极客时间】MySQL 必知必会-20230901
03 | 表:怎么创建和修改数据表? 新增数据表 CREATE DATABASE demo;CREATE TABLE goodsmaster (barcode TEXT,goodsname TEXT,price DOUBLE, itemnumber INT PRIMARY KEY AUTO_INCREMENT);INSERT INTO demo.goodsmaster (barcode, goodsname,price) VAL…...
53 个 CSS 特效 3(完)
53 个 CSS 特效 3(完) 前两篇地址: 53 个 CSS 特效 153 个 CSS 特效 2 这里是第 33 到 53 个,很多内容都挺重复的,所以这里解释没之前的细,如果漏了一些之前的笔记会补一下,写过的就会跳过。…...
简单数学题:找出最大的可达成数字
来看一道简单的数学题:力扣2769. 找出最大的可达成数字 题目描述的花里胡哨,天花乱坠,但这道题目非常简单。我们最多执行t次操作,只需每次操作都让x-1,让num1,执行t次操作后,x就变为xtÿ…...
[C++ 网络协议] 套接字的多种可选项
目录 1. 套接字的可选项 2. 获取/设置套接字可选项 2.1 getsockopt函数(获取套接字可选项) 2.2 setsockopt函数(设置套接字可选项) 3. 常用套接字可选项 3.1 SOL_SOCKET协议层的SO_TYPE可选项 3.2 SOL_SOCKET协议层的SO_SN…...
2022年03月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试
第1题:数字变换 给定一个包含 5 个数字(0-9)的字符串, 例如 “02943”, 请将“12345”变换到它。 你可以采取 3 种操作进行变换 (1)交换相邻的两个数字 (2)将一个数字加 1。 如果加 1 后大于 9, 则变为 0 (3)将一个数字加倍。 如果加倍后大于 9,则将其变为加倍后的…...
***数据转换中常用的两个函数 sscanf,sprintf
1、sscanf将字符串转换成想要的整数或浮点数 (HMI屏中输入浮点数据,到mcu后要转换成对应的浮点数据) sscanf(“0.9”,“%f”,getData) /*! \brief 文本控件通知 \details 当文本通过键盘更新(或调用GetControlValue)时,执行此函数 \details 文本控件的内容以字符串形…...
软件工程(十九) 软件测试
软件测试主要了解软件测试的方法和软件的调试。 1、软件测试方法 1.1、测试基本思想 尽早、不断的进行测试 在V模型其实已经凸显出这种思想了程序员避免测试自己设计的程序 因为测试自己设计的程序,其实是不容易发现问题的,因为人从本质上都不愿意找自己的茬。而且由于你的…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
