软件设计模式原则(三)单一职责原则
单一职责原则(SRP)又称单一功能原则。它规定一个类应该只有一个发生变化的原因。所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。
目录
一.定义
二.原理
类的单一职责原则
单一职责原则好处
三.实践
一.定义
每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起——这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。例如:要实现逻辑和界面的分离。
二.原理
如果一个类承担的职责过多,就等于把这些职责耦合在一起了。一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当发生变化时,设计会遭受到意想不到的破坏。而如果想要避免这种现象的发生,就要尽可能的遵守单一职责原则。此原则的核心就是解耦和增强内聚性。
类的单一职责原则
一般一个对象可以分为属性和行为二部分,所以在类的设计时,我们一般把对象的属性抽象成一个BO(Business Object,业务对象),把对象的行为抽象成一个Biz(Business Logic,业务逻辑)。
单一职责原则好处
- 降低类的复杂性:每个类实现单一职责,并且单一职责都有清楚明确的定义,复杂性当然降低
- 提高可读性:类的复杂性降低了,当然提高了可读性了。
- 提高可维护性:类的复杂性降低,可读性好,当然好维护。
- 提高扩展性:变更引起的风险降低,变更是必不可少的,如果接口的单一职责做的好,一个接口修改只对相应的实现类有影响,对其它的接口没有影响,这对系统的扩展性,维护性都是有好处的。
归纳弱点:
- 职责多,引起此类变化的原因也多。后续变更的风险就大。
- 后续需求变更,会造成职责的混乱,类结构的不稳定。
三.实践
举个例子,将一个女孩追到手,有如下两种方式:
方法一
public void ChaseGirl() {SentLetter();DevelopFeeling();MakeVow(); }public void SentLetter() {}public void DevelopFeeling() {}public void MakeVow() {}方法二
public void ChaseGirl() {SentLetterAndDevelopFeeling();MakeVow(); }public void SentLetterAndDevelopFeeling() {}public void MakeVow() {}不难看出,虽然底层的实现逻辑几乎相同,但是方法二中将送情书and发展感情耦合在了一个类中,违反了单一原则:假设有的女孩对情书不屑一顾,那么就要修改认识的方式——但此时也要修改发展感情的方法~这就是典型的耦合性高的开发~
单一职责原则的重心不在于“一”,而是如何拆分“一”:每个设计师都知道软件应该解耦和分层,但难的是何时分,以及如何分——比如有的人就认为建立契机和发展感情应该是一个统一的过程~
因此引出解决的方法:遵守单一职责原则,将不同的职责封装到不同的类或模块中。
类改造:改造后,类的职责单一
原有违背单一职责原则的类如下:
修改后如下:
这种清晰的职责范围划分就是单一职责原则的最佳实践。符合单一职责原则的设计能使类具备高内聚性,让单个模块变得简单易懂,如此才能增强代码的可读性和可复用性。并提高系统的易维护性和易测试性。
相关文章:
软件设计模式原则(三)单一职责原则
单一职责原则(SRP)又称单一功能原则。它规定一个类应该只有一个发生变化的原因。所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原…...
使用Postman创建Mock Server
这篇文章将教会大家如何利用 Postman,通过 Mock 的方式测试我们的 API。 什么是 Mock Mock 是一项特殊的测试技巧,可以在没有依赖项的情况下进行单元测试。通常情况下,Mock 与其他方法的主要区别就是,用于取代代码依赖项的模拟对…...
【古月居《ros入门21讲》学习笔记】15_ROS中的坐标系管理系统
目录 说明: 1. 机器人中的坐标变换 tf功能包能干什么? tf坐标变换如何实现 2. 小海龟跟随实验 安装 ros-melodic-turtle-tf 实验命令 运行效果 说明: 1. 本系列学习笔记基于B站:古月居《ROS入门21讲》课程,且使…...
初始linux:文件操作
目录 提示:以下指令均在Xshell 7 中进行 linux的理念 一、echo echo "字符串" 二、输出重定向 > > [文件] echo "字符串" > [文件] echo "字符串" > > [文件] 制作大文件 三、< 输入重定向与ca…...
iOS上传ipa使用可视化工具Transporter
文章目录 前言一、Transporter二、Appuploader三、iTMSTransporter总结 前言 最近为了让非开发人员上传IPA文件,特意找了一些方法,至于以前的ApplicationUploader已经不能用了,下面介绍两个工具可以上传IPA包。 一、Transporter 1、操作简单…...
解读《陆奇最新演讲实录—我的大模型世界观》
腾讯科技频道记者张小珺一篇《陆奇最新演讲实录—我的大模型世界观》刷爆朋友圈。文章知识点丰富、字里行间处处流淌着创业方法论和AI应用商机,含金量极高! PS:一家之言、不求苟同。如有不爽之处,欢迎来 找我。 腾讯新闻原文&am…...
ChatGPT到底是如何运作?
自从2022年11月30日发布以来,ChatGPT一直占据着科技届的头条位置,随着苹果的创新能力下降,ChatGPT不断给大家带来震撼,2023年11月7日,首届OpenAI开发者大会在洛杉矶举行,业界普遍认为,OpenAI的开…...
学习Java第57天,Servlet的基本使用步骤
步骤1 开发一个web类型的module 步骤2 开发一个UserServlet public class UserServlet extends HttpServlet {Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取请求中的参数String usern…...
解决:ValueError: must have exactly one of create/read/write/append mode
解决:ValueError: must have exactly one of create/read/write/append mode 文章目录 解决:ValueError: must have exactly one of create/read/write/append mode背景报错问题报错翻译报错位置代码报错原因解决方法今天的分享就到此结束了 背景 在使用…...
大数据-之LibrA数据库系统告警处理(ALM-37014 Gaussdb进程锁文件已经存在)
告警解释 当集群中的CN实例或者DN实例锁文件创建失败时,产生该告警。 告警属性 告警ID 告警级别 可自动清除 37014 严重 是 告警参数 参数名称 参数含义 ServiceName 产生告警的服务名称 RoleName 产生告警的角色名称 HostName 产生告警的主机名 I…...
STM32 基础知识
1. STM32微控制器的核心特性是什么? STM32微控制器是基于ARM Cortex-M 处理器 , 它具有高性能处理能力和低功耗的特性 , 适合用于嵌入式系统STM32系列具有多种多样的内存大小和丰富的内置外设选项,包括 多通道ADC , 定…...
JVM——产生内存溢出原因
目录 1.产生内存溢出原因一 :代码中的内存泄漏1.案例1:equals()和hashCode()导致的内存泄漏问题:**正常情况**:**异常情况:**解决方案: 2.案例2:内部类引用外部类问题:解决方案&…...
关于X86机器上运行GnuCobol的研究
1.安装GnuCobol 当前的稳定版本是 3.1.2,已经在各种平台上进行了广泛测试,并已投入商用。 下载地址为: https://phoenixnap.dl.sourceforge.net/project/gnucobol/gnucobol/3.1/gnucobol- 3.1.2.tar.bz2 1)上传压缩包至x86服务器; 2)通过tar -xvf gnucobol-3.1.2.tar.bz2…...
open与openat的区别
Linux 中的 open 和 openat 系统调用都用于打开文件,但它们有一些区别。 一、函数原型 open 系统调用的原型 #include <fcntl.h>int open(const char *pathname, int flags, mode_t mode);pathname 是要打开的文件路径flags 是打开文件的标志mode 是文件的…...
人工智能与供应链行业融合:预测算法的通用化与实战化
前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 让我们一起深入探索人工智能与供应链的融合,以及预测算法在实际应用中的价值!🔍🚀 文章目录 前言供应链预测算法的基本流程统计学习模型与机…...
Cytoscape学习教程
写在前面 今天分享的内容是自己遇到问题后,咨询社群里面的同学,帮忙解决的总结。 关于Cytoscape,对于做组学或生物信息学的同学基本是陌生的,可能有的同学用这个软件作图是非常溜的,做出来的网络图也是十分的好看,“可玩性”很高,就像前面分享的aPEAR包一样aPEAR包绘制…...
computed和watch相关
Computed本质是一个具备缓存的watcher,依赖的属性发生变化就会更新视图。 适用于计算比较消耗性能的计算场景。当表达式过于复杂时,在模板中放入过多逻辑会让模板难以维护,可以将复杂的逻辑放入计算属性中处理 computed擅长处理:一…...
反思一次效能提升
前天与一个大佬交流。想起自己在6年多前在团队里做的一次小小的效能提升。 改进前 在同一个产品团队,同时有前端工程师和后端工程师。他们经常需要共同协作完成features。 前端是一个传统的多页应用。前端渲染是由后端的velocity模板引擎实现的。 打包后,…...
ElasticSearch之cat indices API
命令样例如下: curl -X GET "https://localhost:9200/_cat/indices?vtrue&pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"执行结果输出如下: health status index uuid …...
Composer update 跳过指定依赖
在使用Compose进PHP 依赖管理只时,有时候我们可能希望忽略版本批配,即使依赖项的景新版本已经发布,也然续使用当前的乐本。这种情况下,我们可以使用Composer的 --ignore-platform-reqs 选项来实现 可以使用--ignore-platform-req…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

