七大设计原则之单一职责原则应用

news/2024/4/27 19:44:35/文章来源:https://blog.csdn.net/ZGL_cyy/article/details/128996260

目录

  • 1 单一职责原则介绍
  • 2 单一职责原则应用


1 单一职责原则介绍

单一职责(Simple Responsibility Pinciple,SRP)是指不要存在多于一个导致类变更的原因。假设我们有一个 Class 负责两个职责,一旦发生需求变更,修改其中一个职责的逻辑代码,有可能会导致另一个职责的功能发生故障。这样一来,这个 Class 存在两个导致类变更的原因。如何解决这个问题呢?

我们就要给两个职责分别用两个 Class 来实现,进行解耦。后期需求变更维护互不影响。这样的设计,可以降低类的复杂度,提高类的可读性,提高系统的可维护性,降低变更引起的风险。总体来说就是一个 Class/Interface/Method 只负责一项职责。

2 单一职责原则应用

接下来,我们来看代码实例,还是用课程举例,我们的课程有直播课和录播课。直播课不能快进和快退,录播可以可以任意的反复观看,功能职责不一样。还是先创建一个 Course 类:

    public class Course {public void study(String courseName){if("直播课".equals(courseName)){System.out.println("不能快进");}else{System.out.println("可以任意的来回播放");}}}

看代码调用:

    public static void main(String[] args) {Course course = new Course();course.study("直播课");course.study("录播课");}

从上面代码来看,Course 类承担了两种处理逻辑。假如,现在要对课程进行加密,那么直播课和录播课的加密逻辑都不一样,必须要修改代码。而修改代码逻辑势必会相互影响容易造成不可控的风险。我们对职责进行分离解耦,来看代码,分别创建两个类 ReplayCourse 和 LiveCourse:

LiveCourse 类:

    public class LiveCourse {public void study(String courseName){System.out.println(courseName + "不能快进看");}}

ReplayCourse 类:

    public class ReplayCourse {public void study(String courseName){System.out.println("可以任意的来回播放");}}

调用代码:

    public static void main(String[] args) {LiveCourse liveCourse = new LiveCourse();liveCourse.study("直播课");ReplayCourse replayCourse = new ReplayCourse();replayCourse.study("录播课");}

业务继续发展,课程要做权限。没有付费的学员可以获取课程基本信息,已经付费的学员可以获得视频流,即学习权限。那么对于控制课程层面上至少有两个职责。我们可以把展示职责和管理职责分离开来,都实现同一个抽象依赖。设计一个顶层接口,创建 ICourse 接口:

    public interface ICourse {//获得基本信息String getCourseName();//获得视频流byte[] getCourseVideo();//学习课程void studyCourse();//退款void refundCourse();}

我们可以把这个接口拆成两个接口,创建一个接口 ICourseInfo 和 ICourseManager:
ICourseInfo 接口:

    public interface ICourseInfo {String getCourseName();byte[] getCourseVideo();}

ICourseManager 接口:

    public interface ICourseManager {void studyCourse();void refundCourse();}

来看一下类图:
在这里插入图片描述
下面我们来看一下方法层面的单一职责设计。有时候,我们为了偷懒,通常会把一个方法写成下面这样:

    private void modifyUserInfo(String userName,String address){userName = "Oldlu";address = "Shandong";}

还可能写成这样:

    private void modifyUserInfo(String userName,String... fileds){userName = "Oldlu";
// address = "Shandong";}private void modifyUserInfo(String userName,String address,boolean bool){if(bool){}else{}userName = "Oldlu";address = "Shandong";}

显然,上面的 modifyUserInfo()方法中都承担了多个职责,既可以修改 userName,也可以修改
address,甚至更多,明显不符合单一职责。那么我们做如下修改,把这个方法拆成两个:

    private void modifyUserName(String userName){userName = "Oldlu";}private void modifyAddress(String address){address = "Shandong";}

这修改之后,开发起来简单,维护起来也容易。但是,我们在实际开发中会项目依赖,组合,聚合这些关系,还有还有项目的规模,周期,技术人员的水平,对进度的把控,很多类都不符合单一职责。

但是,我们在编写代码的过程,尽可能地让接口和方法保持单一职责,对我们项目后期的维护是有很大帮助的。

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

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

相关文章

有什么免费好用的全球天气api?

简单介绍几个,选你觉得合适的就行。(下面推荐的国内外的都有,访问速度会有些差别) 高德天气 API -天气查询-API文档-开发指南-Web服务 API | 高德地图API知心天气 API -HyperData 数据产品简介 心知天气和风天气 API -和风天气开…

Java、JSP动漫网站的设计与实现

技术:Java、JSP等摘要:随着科技的迅速发展,计算机技术已应用到社会的各个领域。随着计算机技术和通信技术的迅速发展,网络的规模也逐渐增大,网络的元素也随之不断增加,有的利用其通信,有的利用其…

架构方法论

0.缘起最近在和同事以及相关领域的人沟通时,大家都在强调架构、架构图,于是兴起了一片关于架构的方法论介绍。本文对内容的组织按照顶层设计思路,先对架构本身进行剖析:什么是架构?为什么架构很重要?这些是…

SNI生效条件 - 补充nginx-host绕过实例复现中SNI绕过的先决条件

文章目录1.前置环境搭建2.测试SNI生效条件(时间)3. 证书对SNI的影响3.1 双方使用同一个证书:3.2 双方使用不同的证书与私钥4. 端口号区分测试4.1 端口号区分,证书区分:4.2 端口号区分,证书不区分:5.总结SNI运行机制6. SNI机制绕过…

SpringBoot+Vue实现智能物流管理系统

文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏…

线程和QObjects

QObject的可重入性: QThread继承了QObject,它发出信号以指示线程开始或完成执行,并提供一些插槽。 QObjects可以在多个线程中使用发出调用其他线程中槽的信号,并将事件发布到在其他线程中“活动”的对象。这是可能的&#xff0…

一个测试人员,在现阶段的环境下如何在测试行业发展和自我价值。

前言周末和几个测试圈子里的大佬饭局上聊了一些职场和测试职业发展相关的话题,我将聊天的内容做了整理和阐述。。朋友圈有测试同学对这篇文章提了比较深刻的建议,下面是他的评价和建议:评价:据说是大佬饭桌总结,有两点…

ThingsBoard-实现定时任务调度器批量RPC

1、概述 ThingsBoard-CE版是不支持调度器的,只有PE版才支持,但是系统中很多时候需要使用调度器来实现功能,例如:定时给设备下发rpc查询数据,我们如何来实现呢?下面我将教你使用巧妙的方法来实现。 2、使用什么实现 我们可以使用规则链提供的一个节点来实现,这个节点可…

【手写 Vuex 源码】第七篇 - Vuex 的模块安装

一,前言 上一篇,主要介绍了 Vuex 模块收集的实现,主要涉及以下几个点: Vuex 模块的概念;Vuex 模块和命名空间的使用;Vuex 模块收集的实现-构建“模块树”; 本篇,继续介绍 Vuex 模…

Elasticsearch7.8.0版本进阶——分布式集群(应对故障)

目录一、Elasticsearch集群的安装1.1、Elasticsearch集群的安装(win10环境)1.2、Elasticsearch集群的安装(linux环境)二、应对故障(win10环境集群演示)2.1、启动集群(三个节点)2.2、…

利用git reflog 命令来查看历史提交记录,并使用提交记录恢复已经被删除掉的分支

一.问题描述 当我们在操作中手误删除了某个分支,那该分支中提交的内容也没有了,我们可以利用git reflog这个命令来查看历史提交的记录从而恢复被删除的分支和提交的内容 二.模拟问题 1.创建git仓库,并提交一个文件 [rootcentos7-temp /da…

TrueNas篇-trueNas Scale安装

安装TrueNAS Scale 在尝试trueNas core时发下可以成功安装,但是一直无法成功启动,而且国内对我遇见的错误几乎没有案例,所以舍弃掉了,而且trueNas core是基于Linux的,对Linux的生态好了很多,还可以可以在t…

最强大的人工智能chatGPT不会还有人没用过吧,再不用就out了

🔗 运行环境:chatGPT 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 #### 防伪水印——左手の明天 #### 💗 大家好🤗&#x1f9…

Win11下Linux子系统迁移方法及报错解决

Win11 将Linux子系统从C盘迁移到其他盘Win11下Linux子系统迁移方法及报错解决1、下载LxRunOffline2、ERROR:directory is not empty 报错解决参考链接Win11下Linux子系统迁移方法及报错解决 C盘满了,Ubuntu子系统占了100多G怎么办?直接将子系…

一文讲清chatGPT的发展历程、能力来源和复现它的关键之处

1. ChatGPT是什么 chatGPT是什么?这可能是最近被问的最多的一个。 大家第一反应这应该是GPT系列的一个最新模型,普通大众可能更愿意把它看做是一个人工智能。实际上,它其实就是一个基于大规模语言模型的对话系统产品。官网对它定义十分的明…

【三维点云】01-激光雷达原理与应用

文章目录内容概要1 激光雷达原理1.1 什么是激光雷达?1.2 激光雷达原理1.3 激光雷达分类三角法TOF法脉冲间隔测量法幅度调制的相位测量法相干法激光雷达用途2 激光雷达安装、标定与同步2.1 激光雷达安装方式考虑因素2.2 激光雷达点云用途2.3 数据融合多激光雷达数据融…

【蓝桥杯单片机】Keil5中怎么添加STC头文件;从烧录软件中添加显示添加成功后新建工程时依旧找不到

蓝桥杯单片机的芯片型号:IAP15F2K61S2 添加头文件:STC15F2K60S2.H 【1】如何通过烧录软件添加STC头文件: 从ATC-ISP的Keil仿真设置中添加(同时自动下载仿真驱动)仔细阅读添加说明 KEIL5添加STC芯片库_Initdev的博客-…

【寒假day4】leetcode刷题

🌈一、选择题❤1.下列哪一个是析构函数的特征( )。A: 析构函数定义只能在类体内 B: 一个类中只能定义一个析构函数 C: 析构函数名与类名相同 D: 析构函数可以有一个或多个参数答案:B答案解析:析构函数是构造函…

C语言(文件输入输出操作)

目录 一.文件 1.文件概念 2.文本模式和二进制模式 (1)模式结尾映射 (2)存储精度 3.I/O级别 一.文件 1.文件概念 文件:在磁盘或固态硬盘上一段已命名的存储区。对于C来说,文件就是一系列连续的字节,每个字节都能被单独读取(在计算机当…

.Net Core对于`RabbitMQ`封装分布式事件总线

首先我们需要了解到分布式事件总线是什么;分布式事件总线是一种在分布式系统中提供事件通知、订阅和发布机制的技术。它允许多个组件或微服务之间的协作和通信,而无需直接耦合或了解彼此的实现细节。通过事件总线,组件或微服务可以通过发布或…