设计原则-单一职责原则

news2024/11/28 0:39:19

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

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

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

一、单一职责原则概念

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

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

二、职责划分

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

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

三、原则适用对象

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

四、实际应用

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

【其他参考】

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IMU 积分进行航迹推算

IMU 积分进行航迹推算 Reference https://github.com/gaoxiang12/slam_in_autonomous_driving 1.0 递推方程推导 \quad 连续时间内的 IMU 运动学方程: R ˙ R ω ∧ q 1 2 q ω ˙ p ˙ v v ˙ a \dot{\mathbf{R}}\mathbf{R}\omega ^{\wedge} \\ \dot{\mathbf{…

[CTF/网络安全] 攻防世界 weak_auth 解题详析

[CTF/网络安全] 攻防世界 weak_auth 解题详析 弱认证弱认证绕过方法姿势Burp Suite 爆破 总结 题目描述:小宁写了一个登陆验证页面,随手就设了一个密码。 弱认证 weak_auth翻译:弱认证 这个术语通常用来描述一种较弱的安全认证方法或机制&am…

HTML语法、常用标签、表单,CSS选择器。简单登录页面的实现

HTML和CSS粗略介绍 文章目录 HTML和CSS粗略介绍HTML页面第一个HTML页面添加图片和视频 HTML语法规范div标签span标签转义字符 HTML常用标签换行和分割线标题超链接列表元素表格 HTML表单输入框和按钮多行文本 CSS样式CSS选择器input标签选择器id选择器类选择器 组合选择器和优先…

【HackTheBox Bagel】打靶记录

一、namp扫描到5000 8000 22 端口 二、访问8000端口,看到跳转到域名bagel.htb,加入到hosts 看到该url 像文件包含,尝试fuzz一波 尝试找公私钥均未果,找到了cmdline 进一步对其包含 HTTP/1.1 200 OK Server: Werkzeug/2.2.2 …

Java多线程异常处理

文章目录 一. 线程中出现异常的处理1. 线程出现异常的默认行为2. setUncaoughtExceptionHandler()方法处理异常3. setDefaultUncaoughtExceptionHandler()方法进行异常处理 二. 线程组内出现异常 一. 线程中出现异常的处理 1. 线程出现异常的默认行为 当单线程中初出现异常时…

工业缺陷检测数据及代码(附代码)

介绍 目前,基于机器视觉的表面缺陷检测设备已广泛取代人工视觉检测,在包括3C、汽车、家电、机械制造、半导体与电子、化工、制药、航空航天、轻工等多个行业领域得到应用。传统的基于机器视觉的表面缺陷检测方法通常采用常规图像处理算法或人工设计的特征加分类器。一般而言…

【Tomcat下载及使用说明】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 1.什么是Tomcat 2.Tomcat下载流程及注意问题 …

Eclipse将代码收缩if/for/try,支持自定义区域收缩

Hi, I’m Shendi Eclipse将代码收缩if/for/try,支持自定义区域收缩 最近忙于给网站增加功能,在使用 Eclipse 编写 Java 代码时发现一个函数内代码过多,并且 if,for,try这种代码块无法收缩(在IDEA&#xff0…

【快速入门-简单实现】使用Java实现的单播、组播和广播

说明 TCP是一个面向连接的协议,TCP一定是点对点的,一点是两个主机来建立连接的,基于TCP实现的肯定是单播(但单播还可以使用UDP协议实现)。只有UDP才会使用广播和组播。 Java中的单播、组播和广播可以使用TCP或UDP协议来实现,具体取决于应用程…

【C语言】实现猜数字游戏——随机数

🚩纸上得来终觉浅, 绝知此事要躬行。 🌟主页:June-Frost 🚀专栏:C语言 该篇将对 选择与循环语句 进行运用,实现猜数字游戏。 需求:游戏后可以选择再次进行游戏,也可以选择…

【Java-Crawler】HttpClient+Jsoup实现简单爬虫

Java编写网络爬虫 网络爬虫1. 爬虫入门程序 网络爬虫1. 网络爬虫的介绍2. 为什么学习网络爬虫 HttpClient1. Get请求2. 带参数的GET请求3. Post请求4. 带参数的 Post 请求5. 连接池6. 请求参数 Jsoup1. jsoup 介绍2.1 功能1.1-解析url2.2 功能1.2-解析字符串2.3 功能1.3-解析文…

由浅入深Dubbo核心源码剖析环境介绍

目录 1 框架介绍1.1 概述1.2 运行架构1.3 整体设计 2 环境搭建2.1 源码拉取2.2 源码结构2.3 环境导入2.4 测试2.5 管理控制台 1 框架介绍 1.1 概述 Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能&#…

ARM学习笔记_1 模式,寄存器,流水线

ARM arm体积小功耗低性能高,支持thumb ARM双指令集,兼容8/16位器件;大量使用寄存器,指令定长,寻址简单。 ARM是32位架构,Word 32bit, half Word 16bit. 模式 用户模式是用户程序的模式&#…

解决MySQL无法输入中文字符的问题

文章目录 问题描述问题排查解决方案1️⃣创建数据库时设置字符集为utf82️⃣修改数据库配置文件【比较麻烦】 写在最后 前几日在使用MySQL数据库的时候,出现了一处保存,故作此记录✍ 问题描述 下面是我这样exam表的结构 mysql> desc exam; --------…

PETR 论文学习

1. 解决了什么问题? DETR3D 为端到端的 3D 目标检测提供了一个思路。但是,DETR3D 中的 2D 到 3D 的变换会带来一些问题。 Reference point 的预测坐标可能不够准确,采样特征可能位于目标区域之外;只有映射点周围的特征会被选取&…

“超越极限 - 如何使用 Netty 高效处理大型数据?“ - 掌握 Netty 技巧,轻松应对海量数据处理!

1 写大型数据 因为网络饱和的可能性,如何在异步框架中高效地写大块的数据是特殊问题。由于写操作是非阻塞的,所以即使没有写出所有的数据,写操作也会在完成时返回并通知 ChannelFuture。当这种情况发生时,如果仍然不停地写入&…

2023年最受欢迎的低代码平台排行榜

随着企业寻找在降低成本的同时加快软件开发的方法,低代码开发平台正变得越来越受欢迎。这些平台允许开发人员使用拖放界面和预置组件,以最少的代码创建复杂的应用程序。它不仅帮助企业加快了数字化转型的脚步,而且打破业务部门和IT部门之间的…

多元分类预测 | Matlab萤火虫算法(FA)优化BP神经网络分类预测,FA-BP分类预测,多特征输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab萤火虫算法(FA)优化BP神经网络分类预测,FA-BP分类预测,多特征输入模型,多特征输入模型,多特征输入模型,多特征输入模型,多特征输入模型,多特征输入模型 多特征输入单输出的二分类及多…

商品领域十二张基础表设计思路与实现

欢迎大家关注公众号「JAVA前线」查看更多精彩分享文章,主要包括源码分析、实际应用、架构思维、职场分享、产品思考等等,同时欢迎大家加我微信「java_front」一起交流学习 1 文章概述 商品在电商领域中是一个非常重要的领域,交易行为前提是有…

Selenium + Java 的环境搭建

Selenium Java 的环境搭建 🔎Chrome 浏览器下载 Chrome 浏览器检查对应版本下载 Chrome 浏览器驱动 🔎配置环境变量🔎验证环境是否搭建成功🔎关于 pom.xml 出现错误的解决方案 🔎Chrome 浏览器 下载 Chrome 浏览器 下…