设计模式六大原则之:单一职责原则

devtools/2024/10/18 20:15:52/

1. 单一职责简介

设计模式中的单一职责原则(‌Single Responsibility Principle, SRP)‌是面向对象设计中的一个基本原则,‌它强调一个类应该仅有一个引起它变化的原因。‌换句话说,‌一个类应该负责一组相对独立且紧密相关的职责,‌并且当这个类需要变更时,‌变更的原因应该只有一个。‌

单一职责原则”是开发生命周期中一个非常重要的原则,它旨在指导开发者如何组织代码,使得每个模块、类或函数都只负责一项特定的任务或职责。

2. 单一职责核心思想

SRP的核心思想(基本理念)是,一个对象应该只关注一件事,即它的责任仅限于执行一个明确的业务功能。这个原则由罗伯特·C·马丁(Robert C. Martin)在其著作《Clean Code》中首次明确提出,其目的是提高代码的可读性、可维护性和模块间的独立性。当一个类承担了过多的功能,例如处理输入、计算结果、输出结果等混合在一起时,会变得难以理解和修改。这样的设计不利于团队协作,也容易引发错误。

主要特性如下:

2.1 职责分离

将不同的职责分离到不同的类或模块中,‌有助于降低系统的复杂性,‌提高系统的可维护性。‌

2.2 高内聚低耦合

遵循单一职责原则的类通常具有较高的内聚性(‌即类的内部元素之间联系紧密)‌和较低的耦合性(‌即类与类之间的依赖关系简单)‌。‌

2.3 易于扩展

当系统需要增加新功能时,‌可以更容易地通过添加新的类来实现,‌而不是修改现有的类。‌

3. 单一职责应用场景

遵循单一职责原则有助于创建更具弹性的系统,它的应用场景主要体现在如下几个方面:

3.1 职责识别

首先,‌需要仔细分析类的职责,‌确保每个类都只有一个明确的职责。‌如果发现一个类承担了多个职责,‌那么应该考虑将这些职责分离到不同的类中。‌

3.2 重构代码

在识别出类的多个职责后,‌可以通过重构代码来将这些职责分离。‌这通常涉及到将类拆分成多个更小的类,‌每个类都负责一个单一的职责。‌

3.3 接口隔离

单一职责原则也适用于接口设计。‌一个接口应该只包含一组紧密相关的方法,‌而不应该包含与接口主要目的无关的方法。‌这有助于保持接口的简洁和清晰。‌

4. 单一职责使用步骤

  1. 清晰定义类边界:确定一个类应该包含哪些行为,以及应该对外提供什么样的接口。理想情况下,这个接口应该是最小化的,只包含完成其职责所需的操作。

  2. 将复杂功能拆分:如果某个功能过于庞大,考虑将其分解为几个更小、更专注的函数或类。这可以提高代码的复用性,并使其更容易测试。

  3. 避免过度继承:过多的继承可能导致类变得臃肿,难以理解。除非有明确的继承关系和共享行为,否则通常建议选择组合而非继承。

  4. 尽量使用接口和抽象类:它们可以帮助封装职责并提供统一的行为规范,让具体的实现细节隐藏起来。

  5. 遵循高内聚低耦合原则:一个类内部应该高度关联,对外则尽可能地松散耦合。这样可以确保当其中一个部分改变时,不会对其他部分造成大的影响。

  6. 定期审查代码:定期评估类的职责是否仍然清晰,是否有需要重构的地方。如果发现某类职责范围过大,可能是时候拆分成两个或更多的类了。

5. 单一职责代码示例

现在假设我们有一个类Vehicle,它负责汽车的行驶和停车功能。如果汽车行驶逻辑发生变化,或者停车逻辑发生变化,那么Vehicle类就会受到影响,这违反了单一职责原则。解决这个问题的方法是将行驶和停车功能分离到不同的类中,例如DriveControllerParkingSystem

5.1 违反单一职责的代码设计Vehicle

// 违反单一职责的设计
class Vehicle
{public void drive() {// 实现行驶逻辑}public void park() {// 实现停车逻辑}
}

5.2 用单一职责思想拆分Vehicle

// 行驶控制器
class DriveController {public void drive() {// 实现行驶逻辑}
}// 停车系统
class ParkingSystem {public void park() {// 实现停车逻辑}
}// 使用示例
public class SingleResponsibilityPrincipleExample {public static void main(String[] args) {DriveController driveController = new DriveController();driveController.drive();ParkingSystem parkingSystem = new ParkingSystem();parkingSystem.park();}
}

在这个例子中,DriveController类只负责汽车的行驶功能,而ParkingSystem类只负责汽车的停车功能。这样一来,如果行驶逻辑或停车逻辑发生变化,只需修改对应的类即可,不会影响其他部分的代码。这就是单一职责原则的应用。

6. 总结

综上所述,单一职责原则(Single Responsibility Principle, SRP) 是面向对象设计中的一个基本原则,它提倡一个类或者一个模块应当只有一个引起它变化的原因。简单来说,就是每个类应负责一个明确的任务,并且这个任务只有一个原因导致其改变。以下是这个原则的一些关键点:

  1. 定义清晰: 类应有明确且具体的职责,使其能完成单一目标,比如管理数据库连接,或者处理用户请求。

  2. 高内聚: 类内的所有方法应该密切相关的服务于同一项功能,彼此之间相互独立,互不影响。

  3. 低耦合: 类之间的依赖程度尽量低,这样当一个类需要更改时,不会波及到其他无关的类,提高了代码的稳定性。

  4. 避免过多功能: 避免在一个类中包含过多的特性或行为,每个类都应该有自己的专业领域,减少复杂性。

  5. 可扩展性: 当需求变化时,由于职责明确,只需修改负责那部分职责的部分即可,不需要牵涉全局。

  6. 易于测试: 因为职责集中,单个类的单元测试相对简单,有利于测试驱动开发(TDD)。

  7. 利于重构: 单一职责有助于识别并孤立出可以独立调整的代码块,使得重构变得更简单。

遵循单一职责原则有助于编写出易于理解、稳定和可维护的代码。然而,也要注意过犹不及,适度的职责划分才能保持设计的平衡。


http://www.ppmy.cn/devtools/95064.html

相关文章

软件需求设计分析报告(Word原件)

第1章 序言 第2章 引言 2.1 项目概述 2.1.1 项目背景 2.1.2 项目目标 2.2 编写目的 2.3 文档约定 2.4 预期读者及阅读建议 第3章 技术要求 3.1 软件开发要求 3.1.1 接口要求 3.1.2 系统专有技术 3.1.3 查询功能 3.1.4 数据安全 3.1.5 可靠性要求 3.1.6 稳定性要求 3.1.7 安全性…

从JVM分析对象创建的过程

从JVM分析对象创建的过程 如图: 1.类加载检查 虚拟机遇到一条new指令时,首先去检查这个指令的参数是否能在称量翅中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化过。如果没有,先对这个类…

RPA财务机器人是什么,RPA的具体应用场景有哪些?| 实在RPA研究

越来越多的人工智能及超自动化技术在企业财务工作中得以普及应用,以提升财务工作效率,促进财务部门实现全面数字化转型。 RPA财务机器人是什么? RPA,即机器人流程自动化(Robotic Process Automation)&#…

HCIP | 重发布实验

要求: 1.如图搭建网络拓扑,所有路由器各自创建一个环回接口,合理规划IP地址 2.R1-R2-R3-R4-R6之间使用OSPF协议,R4-R5-R6之间使用RIP协议 3.R1环回重发布方式引入OSPF网络 4.R4/R6上进行双点双向重发布 5.分析网络中出现路由…

基于深度学习的跨领域生成

基于深度学习的跨领域生成是生成式模型技术的重要方向,旨在将一个领域中的数据或信息转化为另一领域的表现形式。这种技术在艺术、设计、内容创作等领域有广泛应用,并不断发展出新颖的应用场景。下面是对这一主题的详细介绍: 1. 背景与动机 …

CRM客户关系管理系统

本文来自:CRM客户关系管理系统 - 源码1688 应用介绍 基于ThinkPHPFastAdmin开发的CRM客户关系管理系统 后台演示:https://crmdemo.rycl.vip/admin11.php uniapp小程序演示: 搭建教程1,框架离线安装:https://yuanma168…

flink车联网项目前篇:数据开发(第66天)

系列文章目录 03_数据仓库开发 开发规范 1.1 数据库划分规范 1.2 表命名规范 1.3 表字段类型规范开发前准备 3.1 业务系统表 3.2 数据导入 04_维度主题相关表结构 1.1 dim_area - 城市字典表 1.2 dim_car_info - 车辆信息表 1.3 dim_car_vendor - 车队信息表 1.4 dim_date_wo…

豆瓣电影排行榜数据爬取

爬虫流程 确定需求 标题,图片链接,评分找到数据所在链接 [https://movie.douban.com/chart?t1477886984558](https://movie.douban.com/chart?t1477886984558) 构造请求头向服务器发送请求 添加UA解析数据 使用bs4进行解析数据存储数据 可以把数…