设计原则-单一职责原则

在编程大环境中,评价代码组织方式质量的好坏涉及到各个方面,如代码的可读性、可维护性、可复用性、稳定性等各个方面。而在面向对象语言中也可以通过以下各个方面:

  • 类中方法的设计
  • 类中属性的设计
  • 类(接口、抽象类、普通类)的设计
  • 类与类之间的关联关系(组合、继承、实现)的设计

设计原则(SOLID)也是在这些方面可能出现的问题中总结出来的,虽然并不一定能够全部都满足原则要求,但是尽可能满足更能够提到代码组织质量。本文下面将逐步分析单一职责原则的具体含义以及应用。

一、单一职责原则概念

单一职责原则(Single Responsibility Priciple, SRP)规定了代码中的类应该有且仅有一个原因引起类的变更。换句话说,一个类仅负责单一业务职责,意味着仅当该职责发生改变时,该类才需要被改动。相反,类改动后,仅该类负责的业务逻辑改动同时不影响其他业务逻辑。
由此可以看出,单一职责原则提出了一个编程标准,用“变化原因”、“职责”等来衡量一个类的设计的合理性

类的职责唯一性首先能够显著提高代码的可读性,一般来说,日常开发中书写的类名基本按照其功能或职责来进行命名,单一职责的类代码维护起来十分方便,增加开发效率。如果类的职责不唯一,当其中一种业务场景需要改动时,如给类添加一个属性,我们很难判断这次改动是否会影响到其他业务场景,降低了代码的可维护性以及稳定性。

二、职责划分

我们现在知道了类的设计要尽可能的遵循单一职责,即一个类仅负责单一业务职责。设计原则听起来、理解起来都十分简单,但是在实际业务开发中,能够做到类单一职责的项目有多少?完全遵循单一职责进行开发几乎是天人说梦。这其中主要的原因有以下几点:① 不同项目所涉及的业务有所不同,不同业务针对类职责的划分也有所不同。划分太粗不满足单一职责,划分太细类数量急速膨胀,也增加了代码可维护性的难度。② 项目代码基本由多人、跨时空进行开发,每个人对业务理解的不同就会导致类的设计(职责划分)存在差异化。③ 项目中有的类可能根本做不到单一职责原则,比如工具类、启动类等业务功能辅助类以及一些实现类。其中第①个问题是最具备矛盾性,最难把握的问题。那问题是我们又该根据什么如何划分职责呢?
接口、类的职责划分是不可度量的,但也不是无迹可寻、任意划分的。接口职责划分根据项目而异、因环境而异。考虑以下两个场景的区别:
(1) 公司业务主要客服相关,需要你描述下客服的行为过程。在此间你需要设计电话相关类。
在这里插入图片描述
如上图所示,由于电话种类有很多,因此设计了一个IPhone接口。接口中定义了客服需要利用电话执行的业务逻辑,如根据电话号码拨打电话、和客户交谈以及结束通话等操作。
首先思考下,在该场景中,这个电话接口符合单一职责原则吗?符合!因为客服业务不可能拆分电话,自身业务利用的是电话产品,因此电话的接口设计只需要考虑电话制造商提供给其他使用者的接口即可。
② 公司业务主要是电话制造厂相关,需要你描述下电话制造的行为过程。在此间你需要设计电话相关类。
我们还是首先思考下,在该场景中,场景①设计的电话接口符合单一职责原则吗?不符合!因为电话制造厂会涉及到电话原理底层,电话制造生产线中会分为不同的模块,比如电话通信所需要的协议管理、数据传送方式等。如果使用上述统一接口,会导致协议管理发生变化或数据传送方式发生变化都会引起类的变化。
在这里插入图片描述
如上图所示,将原先IPhone接口拆分为两个接口,具体电话实现类同时实现该两个接口,即可。当某一个模块发生改动时,只需要改动该接口相关的即可。

接口职责的划分需要根据具体的业务而定

三、原则适用对象

在上一节例子中,我们将IPhone接口拆分为2个接口,在具体实现类中实现两个接口完成所有功能。那我们为什么不选择组合呢?使用组合方式也能实现需求目标,但是使用组合方式会导致多个实现类间耦合严重、类的数量增加等问题,会增加设计的复杂性。但是,还有个疑问是,不论是通过组合方式还是继承方式,接口虽然是满足单一职责了,但是实现类并不满足单一职责。因为最终还是将两个职责融入到一个类中了。
类的单一职责几乎很难实现,退一步来说,由于我们总是面向接口编程,向外提供的是接口,而不是具体实现类。因此我们必须要保证设计的接口是单一原则的
单一职责原则的本质实际上是要求代码是局部高内聚,低耦合的。因此类的方法也需要尽可能遵循单一职责原则,划分职责的依据也需要根据具体项目来进行划分。

四、实际应用

在实际的业务开发中,尽可能地满足单一职责的设计要求,这样能够保证接口的复杂性降低,实现的业务逻辑都有清晰明确的定义,同时提高了代码可读性、可维护性以及稳定性。在类、方法设计之初,职责的划分最为重要,具体划分依据具体业务而定。一方面考虑业务未来发展是否需要更细粒度的划分,另外一方面根据业务发展现状及时对业务代码进行重构。
在单一职责原则的实际落地过程中,千万不要盲目拆分类,并非是越小、越简单的类越好,相反,这种过分细分类的做法容易导致类的剧增,降低代码可读性以及可维护性。

【其他参考】

  • https://www.jdon.com/58636.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/22687.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

十万条数据,后端不分页咋办!(如何优化长列表渲染)

十万条数据,后端不分页咋办!(如何优化长列表渲染) 长列表是什么? 我们通常把一组数量级很大的数据叫做长列表,比如渲染一组上千条的数据,我们以数组的形式拿到这些信息,然后遍历渲…

正点原子ALPHA开发板核心资源分析

目录 正点原子ALPHA开发板核心资源分析I.MX6ULL实物图对比SOC 主控芯片(MCIMX6Y2CVM08AB)NAND FLASHEMMCDDR3L 正点原子ALPHA开发板核心资源分析 I.MX6ULL实物图对比 I.MX6ULL NAND BTB 接口核心板资源图与 I.MX6ULL EMMC BTB 接口核心板资源图如上图&a…

电商项目9:新增商品

电商项目9:新增商品 1、前端1.1、修复前端组件通信问题1.2、引入其他前端代码1.3、会员等级列表1.4、当前分类关联的所有品牌 2、后端2.1、会员系统搭建(注册与发现)2.2、当前分类关联的所有品牌2.3、获取分类下所有分组&关联属性 1、前端…

shell sed命令

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 sed 命令sed 编辑器sed 的工作流程的三个过程命定格式常用选项常用操作 实验操作打印内容使用地址删除行替换插入 sed 命令 sed 编辑器 sed是一种流编辑器&#x…

听我一句劝,别去外包,干了6年,废了....

先说一下自己的情况,大专生,18年通过校招进入湖南某软件公司,干了接近6年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了6年的功能测试&…

中国移动董宁:深耕区块链的第八年,我仍期待挑战丨对话MVP

区块链技术对于多数人来说还是“新鲜”的代名词时,董宁已经成为这项技术的老朋友。 董宁2015年进入区块链领域,现任中国移动研究院技术总监、区块链首席专家。作为“老友”,董宁见证了区块链技术多个爆发式增长和平稳发展的阶段,…

Doxygen 源码分析: SymbolMap类

2023-05-21 10:59:35 ChrisZZ imzhuofoxmailcom Hompage https://github.com/zchrissirhcz 文章目录 1. Doxygen 版本2. SymbolMap 类概要3. 添加符号: SymbolMap<T>::add()4. 删除符号: SymbolMap<T>::remove()5. 符号查找: SymbolMap<T>::find()6. 哪里用了…

什么是半实物仿真平台自动驾驶半实物仿真平台有哪些?

文章目录 半实物仿真平台介绍自动驾驶半实物仿真平台介绍1.CARLA2.AirSim3.LGSVL Simulator 半实物仿真平台介绍 半实物仿真平台是一种综合利用虚拟仿真和实际硬件设备的仿真系统。它将虚拟环境和真实硬件设备结合起来&#xff0c;旨在提供更真实、更准确的仿真体验。 在半实…

基于html+css的图展示90

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

Boundary IoU:Improving Object-Centric Image Segmentation Evaluation总结笔记

Boundary IoU:Improving Object-Centric Image Segmentation Evaluation&#xff08;边界Iou&#xff1a;改进以对象为中心的图像分割评价&#xff09; 目录 一、论文出发点 二、论文核心思想 三、相关工作 四、敏感度分析 五、Boundary IoU定义和实验证明 六、应用 七…

基于Gabor-小波滤波深度图表面法线的特征提取算法【通过正常Gabor-小波的直方图进行2D或3D特征提取】研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Redis+Lua脚本防止超卖

超卖就是因为查询库存和扣减库存两个操作不是原子性操作&#xff0c;通过rua脚本执行这两个操作可以保证这两个操作原子性 判断库存量是不是大于等于1&#xff0c;如果大于等于1对库存减1&#xff0c;否则就不去减库存 StringBuilder sb new StringBuilder();sb.append("…

【JAVA进阶】Stream流

&#x1f4c3;个人主页&#xff1a;个人主页 &#x1f525;系列专栏&#xff1a;JAVASE基础 目录 1.Stream流的概述 2.Stream流的获取 3.Stream流的常用方法 1.Stream流的概述 什么是Stream流&#xff1f; 在Java 8中&#xff0c;得益于Lambda所带来的函数式编程&#xff0…

使用go语言构建区块链 Part2.工作量证明

英文源地址 简介 在上一篇文章中, 我们构建了一个非常简单的数据结构, 这是区块链数据库的本质.并且我们可以通过它们之间的链式关系来添加区块: 每个区块都链接到前一个区块.哎, 我们的区块链实现有一个重大缺陷: 向链中添加区块既容易又便捷. 区块链和比特币的关键之一是增…

面对当下各种不确定性,如何面对,每天很忙碌,不慌

&#xff08;点击即可收听&#xff09; 疫情时期,都难,疫情之后,发现还更难 随着互联网的热度的下降,各大小公司纷纷勒紧裤腰带,受打击最大的无疑是底层打工人 每天一打开手机,会发现,一些大厂裁员信息霸榜头条,年龄也是一道坎 刚刚看到一个大v发的&#xff1a; 一个原先是跨国…

如何在 OpenSUSE 上安装 VirtualBox 7?

VirtualBox 是一款开源的虚拟化软件&#xff0c;允许用户在单个计算机上运行多个操作系统。本文将详细介绍如何在 OpenSUSE 上安装 VirtualBox 7。以下是安装过程的步骤&#xff1a; 步骤一&#xff1a;下载 VirtualBox 7 首先&#xff0c;我们需要下载 VirtualBox 7 的安装包…

真题详解(语法分析输入记号流)-软件设计(八十)

真题详解&#xff08;求叶子结点数&#xff09;-软件设计&#xff08;七十九)https://blog.csdn.net/ke1ying/article/details/130787349?spm1001.2014.3001.5501 极限编程XP最佳实践&#xff1a; 测试先行、 按日甚至按小时为客户提供可运行的版本。 组件图的 插座 和插头…

Pytorch的CNN,RNNLSTM

CNN 拿二维卷积举例&#xff0c;我们先来看参数 卷积的基本原理&#xff0c;默认你已经知道了&#xff0c;然后我们来解释pytorch的各个参数&#xff0c;以及其背后的计算过程。 首先我们先来看卷积过后图片的形状的计算&#xff1a; 参数&#xff1a; kernel_size &#xff…

使用Linkage Mapper工进行物种分布建模的步骤详解(含实际案例分析)

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Linkage Mapper解密数字世界链接 文章目录 引言:一、介绍二、数据准备2.1 物种分布数据获取2.2 环境变量数据获取2.3 数据预处理

车道线检测

前言 目前&#xff0c;车道线检测技术已经相当成熟&#xff0c;主要应用在自动驾驶、智能交通等领域。下面列举一些当下最流行的车道线检测方法&#xff1a; 基于图像处理的车道线检测方法。该方法是通过图像处理技术从摄像头传回的图像中提取车道线信息的一种方法&#xff0c…