C++通透讲解设计模式:单一职责原则

C++通透讲解设计模式:单一职责原则

理解单一职责原则

这里我总结了一个规律,可以用一句话来表示:

永远只做自己分内的事情

注意,这个"分内的事情"是逻辑上的,什么意思呢?举几个例子。

例子

例子1

我是一个学生,我每天做的事情就是:起床、吃饭、上学、放学、写作业、睡觉(假设要做的事情有这些)

那么这些事情就是我"分内"的事情,什么是"分外"的事情呢?

例如,是谁叫我起床的,谁给我做饭的,谁送我上学的,谁接我放学的,作业是谁布置的等等,这些都不是我分内的事情。

例子2

我是一个公司的员工,我负责人事部的面试管理,那么我"分内"的事情就是:

  • 查看简历
  • 问面试问题
  • 得出面试结果

三件事情,至于我该面试谁,这不重要,面试结果该如何反馈给面试者,这不重要,我要做的事情核心就是考察一个人的水平,然后得出结论。

例子3

一直钢笔,想要让它写字的话需要下面的步骤:

  • 拧开笔管
  • 吸墨水
  • 合上笔管
  • 等待墨水出来
  • 等待别人使用

至于是谁拧开笔管,吸什么样的墨水,被谁使用,这些不重要。

总之,只需要做好自己分内的事情,这样就是单一职责原则。

代码讲解与示范

其实有了上面的例子,就能很简单的理解了,我们首先需要一个需求:

实现一个日志记录,可以设置标题、内容,可以向其中添加日志(为了举例子,删除就先不写了),并且可以将其保存到文件系统中。

思路

为了记录日志,我们可以设计一个日志类,存储日志标题和内容,并且支持相应的操作。

首先来设计日志类的成员和存储:

cpp 复制代码
class Journal {
public:
	string title;
	vector<string> entries;

	explicit Journal(const string &title) : title{title} {}

	void add(const string &entry) {
		static int count = 0;
		entries.push_back(to_string(++count) + ": " + entry);
	}
};

然后我们需要设计将日志存储到文件系统中的功能,这个功能如何实现呢?

有些人会这样设计:

cpp 复制代码
class Journal {
public:
	string title;
	vector<string> entries;

	explicit Journal(const string &title) : title{title} {}

	void add(const string &entry) {
		static int count = 0;
		entries.push_back(to_string(++count) + ": " + entry);
	}
	void save(const string &filename) {
		ofstream ofs(filename);
		for (const auto &entry : entries) {
			ofs << entry << endl;
		}
	}
};

上面这个方式可以正常运行,但是违背了单一职责原则。

还记得一开始说的单一职责原则的规律吗------"只做分内的事"

那么对于一个日志类来说,保存日志信息到文件系统中是否是一个日志类分内的事情呢?

很显然不是,作为一个日志,你的工作应当是存放日志信息(甚至连管理日志信息的工作都没有)

那么很自然的我们就需要设计另一个类去做存储,这里叫他"存储器"吧!

cpp 复制代码
struct PersistenceManager {
	static void save(const Journal &j, const string &filename) {
		ofstream ofs(filename);
		for (const auto &entry : j.entries)
			ofs << entry << endl;
	}
};

整个代码如下:

cpp 复制代码
/********************************************************************
 * > File Name: 单一职责原则.cpp
 * > Author: royi
 * > Mail: royi990001@gmail.com
 * > Created Time: 2024-12-02 19:25:45
 *******************************************************************/
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <functional>
#include <cmath>
#include <ctime>

using namespace std;

#define __NAMESPACE_SRP_BEGIN__ namespace SRP {
#define __NAMESPACE_SRP_END__ }

__NAMESPACE_SRP_BEGIN__

struct Journal {
        string title;
        vector<string> entries;

        explicit Journal(const string &title) : title{title} {}
        void add(const string &entry) {
                static int count = 0;
                entries.push_back(to_string(++count) + ": " + entry);
        }

};

struct PersistenceManager {
        static void save(const Journal &j, const string &filename) {
                ofstream ofs(filename);
                for (const auto &entry : j.entries)
                        ofs << entry << endl;
        }
};

int main() {
        Journal journal("Dear Diary");
        journal.add("I ate a bug");
        journal.add("I cried today");
        PersistenceManager::save(journal, "diary.txt");
        return 0;
}

__NAMESPACE_SRP_END__

int main() {
        SRP::main();
        return 0;
}

:wq 886~~有问题欢迎评论区提问,作者会在一个工作日之内给予回复

相关推荐
cany10001 小时前
C++ -- 可变参数模板
c++
不会C语言的男孩2 小时前
C++ Primer 第2章:变量和基本类型
开发语言·c++
云泽8083 小时前
C++ 可调用对象通关指南:深度解析 Lambda 表达式、function 包装器与 bind 绑定器
开发语言·c++·算法
Tri_Function4 小时前
简单图论大学习
c++
lqqjuly4 小时前
C++ 完整知识体系—从基础语法到现代 C++23 的系统性总结
c++·c++23
王老师青少年编程5 小时前
信奥赛C++提高组csp-s之FHQ Treap
c++·csp·平衡树·信奥赛·csp-s·提高组·fhq treap
QiLinkOS7 小时前
《打破“用爱发电”:一种基于 Gitee 与时间戳的开源权益分配机制探索》
c语言·数据结构·c++·科技·算法·gitee·开源
Irissgwe7 小时前
c++STL--string类
c++·stl·string
Irissgwe7 小时前
c++类型转换
c++·类型转换·explicit·static_cast·const_cast·dynamic_cast·rtti
智者知已应修善业7 小时前
【51单片机用T0定时器方式1,实现0.5S的时间间隔实现第一次一个灯亮、第二次二个灯亮,直到全部灯亮,然后重复整个过程】2023-12-29
c++·经验分享·笔记·算法·51单片机