单一职责原则-Single Responsibility Principle-SRP

本文深入解析单一职责原则,强调一个类只应有一个引起其变化的原因,通过实例展示如何降低类的复杂度,提高代码的可读性和可维护性,减少变更风险。

定义:就一个类而言,应该仅有一个引起其变化的原因。
优点:

  • 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多
  • 提高类的可读性,提高系统的可维护性
  • 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响

举例: 每个老师只教一门课程,则更加专注、高效。(代码较多,只截取重要的片段)

老师拥有教学的方法

// Teacher.h
// 头文件中,声明为虚函数,每个老师都应实现该函数
virtual void teach();

// Teacher.cpp
// 实现
void Teacher::teach()
{
	std::cout << "I teache a course." << std::endl;
}

语文老师的教学函数

void ChineseTeacher::teach()
{
	std::cout << "I teache chinese." << std::endl;
}

数学老师的教学函数

void MathTeacher::teach()
{
	std::cout << "I teache math." << std::endl;
}

客户端

#include "ChineseTeacher.h"
#include "MathTeacher.h"

int main(int agrc, char* argv[])
{
	ChineseTeacher chineseTh;
	MathTeacher mathTh;

	chineseTh.teach();
	mathTh.teach();

	getchar();
	return 0;
}

日后,语文老师和数学老师的教学方式不一样了,只需需改各自的教学函数,而互不影响。

运行结果
在这里插入图片描述
源码地址

<think>我们正在讨论单一职责原则SRP)。根据引用内容,单一职责原则的核心是:一个类应该只有一个引起它变化的原因,或者说只专注于做一件事。这有助于降低类的复杂性,提高可读性和可维护性,并减少变更引起的风险。 引用[2]中有一个很好的例子:一个Modem接口有两个职责(连接管理和数据通信),这违反了SRP。我们可以将其拆分成两个接口:一个处理连接(dial和hangup),另一个处理数据通信(send和recv)。 引用[3]和[4]强调了SRP的好处:降低复杂性、提高可读性、提高可维护性、降低变更风险。 因此,我们可以这样理解SRP: 1. 一个类(或模块、方法)应该只有一个职责。 2. 职责是变化的原因,如果一个类有多个变化的原因,就需要拆分。 下面我们用代码示例来说明: 违反SRP的类: ```java // 这个类负责两个职责:用户信息管理和用户显示 class User { private String name; private String email; // 构造函数等 // 职责1:管理用户信息 public void saveUser() { // 将用户信息保存到数据库 } // 职责2:显示用户信息 public void displayUser() { System.out.println("Name: " + name); System.out.println("Email: " + email); } } ``` 按照SRP拆分后: ```java // 只负责用户信息的存储和获取 class User { private String name; private String email; // getters and setters } // 负责用户信息的持久化 class UserRepository { public void saveUser(User user) { // 保存到数据库 } } // 负责用户信息的显示 class UserDisplay { public void displayUser(User user) { System.out.println("Name: " + user.getName()); System.out.println("Email: " + user.getEmail()); } } ``` 这样,如果用户信息的存储方式变化,我们只需修改UserRepository;如果显示方式变化,只需修改UserDisplay。而User类只负责保存用户数据。 注意:职责的划分并不是绝对的,需要根据具体场景。引用[1]提到,职责的界限并不清晰,需要经验。 总结: 单一职责原则要求我们将不同的职责分离,使得每个类只承担一个职责,从而降低系统的耦合度,提高系统的可维护性。 现在,根据要求,生成相关问题: </think> ### 理解单一职责原则SRP单一职责原则Single-responsibility PrincipleSRP)是面向对象设计的**核心原则**之一,其核心思想可概括为: > **一个类应该只有一个引起变化的原因**(或:一个类只负责一项职责) #### 核心要点解析 1. **职责的定义** 职责即"变化的原因"。如果一个类承担多个职责,当某个职责需求变更时,可能影响其他无关功能。 > "当发现有两个变化会要求修改这个类,就要考虑拆分它"[^2] 2. **设计目标** - 降低类的复杂度:每个类功能单一明确 - 提高可维护性:修改局部化,不影响其他模块 - 增强可读性:类功能一目了然 - 减少变更风险:避免"牵一发而动全身"[^3] #### 违反SRP的典型示例 ```java // 违反SRP:同时负责用户管理和日志记录 class UserManager { public void createUser(String username) { // 1. 创建用户逻辑 System.out.println("Creating user: " + username); // 2. 记录日志(混杂的职责) log("User created: " + username); } private void log(String message) { // 日志记录实现 System.out.println("[LOG] " + message); } } ``` **问题**:当需要修改日志格式或存储方式时,必须修改`UserManager`类,可能影响核心用户管理功能[^4]。 #### 遵循SRP的重构方案 ```java // 职责1:专用户管理 class UserManager { private Logger logger; // 通过依赖注入解耦 public UserManager(Logger logger) { this.logger = logger; } public void createUser(String username) { // 单一职责:用户创建 System.out.println("Creating user: " + username); logger.log("User created: " + username); } } // 职责2:专日志记录 class Logger { public void log(String message) { // 单一职责:日志处理 System.out.println("[LOG] " + message); } } ``` **优势**: - 用户管理变更不会影响日志系统 - 日志策略可独立扩展(如改为文件存储) - 代码可读性和可测试性显著提升 #### SRP的实践指导 1. **职责判断标准** - 检查类的方法是否服务于同一目标 - 分析需求变更时哪些方法会一起修改 - 方法间是否存在"与/或"关系(如保存数据并发送通知) 2. **粒度把握** 避免过度拆分导致"类爆炸",合理场景包括: - 数据持久化与业务逻辑分离 - 界面渲染与数据处理分离 - 核心算法与异常处理分离 3. **设计收益** $$ \text{可维护性} \uparrow \quad \text{耦合度} \downarrow \quad \text{复用性} \uparrow $$ 系统复杂度随规模增加呈线性而非指数增长[^1] > "就像社会分工:专人做专事,系统才高效"[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值