发散式变化、霰弹式修改和单一职责

“发散式变更与霰弹式修改之间的精妙点:单一职责(SRP:Single responsibility principle)”

本文适合以下小伙伴们观看:

  • 遇到过问题:只改一个小功能,却需要修改一堆分散在各处的代码,有时还会漏改
  • 遇到过问题:只改了一行代码,有些地方意外地发生了变化
  • 想要学习或者了解发散式变化、霰弹式修改或单一职责这些概念
  • 想要杀杀时间,看看图

发散式变化

一处代码的修改影响多个功能,称作发散式变化。

在这里插入图片描述

查看​图片的方向:从左向右(CODE->feature)​

负面影响:风险(项目会因此出现更多不确定与风险)

霰弹式修改

一个功能的变更需要多处同时修改,称作霰弹式修改。

在这里插入图片描述
查看​图片的方向:从左向右(CODE->feature)​

负面影响:成本(修改更慢)、风险(修改时更易出错)

怎么办呢?

1 完美的解决方案:单一职责

其实两个问题都是关于代码与功能的关系不匹配的问题。一个是代码多于功能,另一个是功能多于代码。所以只要平衡代码与功能的关系,问题就解决了。

案例解说:一个"存在5段代码 对应 5个功能"的系统优化

首先,有一个系统,它有5个核心功能,同时也有5段代码段。

在这里插入图片描述
图中其实看得到,​现在的系统非常混乱,像一堆线胡乱地缠在一起。

仔细观察可以发现:有五个代表代码段的线条,和五个代表功能(特性)的线条

但中间缠在一块了,仔细看还可以发现,代码段和功能竟然还不是一一对应的。

有一段代码对应三个功能的(图中红色,1份代码对应3个功能);又有三段代码对应一个功能的(图中橙色)。

也就是说,现在系统中既存在发散式变化,又存在霰弹式修改,要是改这块代码可算是倒大霉了。

但读者们可能会有个想法,整理一下,变成这样不就行了吗?

在这里插入图片描述
是的,相当可以!一个代码对应一个功能,真是干净又清晰。​

那接下来,让我来帮你细化一下脑中的想法。

请先看扩充细节的系统结构图:

在这里插入图片描述
图中有几个关键元素:开发人员、用户、系统、核心模块、代码、功能(特征)。

这里解释一下什么是元素
图中表达各种事物的不可再分的最小实体,都是元素。比如,表示关系的线条,表示用户和开发者的小人,甚至表示核心模块的虚线方框都是元素。

图中元素描述:

  • developer(开发者):负责系统设计、开发、维护的人员
  • user(用户):本软件系统的使用者
  • Core(核心):核心模块。有一些核心机制,不是所有开发者都全部了解的
  • Code:N(代码N):编号为N的某段代码
  • feature:N(功能N):编号为N的某功能(或特征)
  • System(系统):被分析的本软件系统

梳理一下各元素关系:

  • 开发者看得到所有元素,但核心模块对开发者算半封闭(并不是全部了解,且不一定能任意修改)
  • 开发者修改代码后,功能就会变化。但不知道哪个会变,甚至不知道几个会变。
  • 用户看得到系统功能,看不到其他元素

现在一起看看用户视角看到的系统是什么样的:

在这里插入图片描述
用户只看得到功能和系统,看不到细节。所以做开发时会遇到那种用户看起来很简单的功能,实际开发起来很麻烦的情况,因为内部结构用户看不到,也不关注。

对于用户来说,五个功能互相并无关联,所以图中使用了5种颜色对功能进行标记。

那我们要怎么做才能做好本次的优化呢?

其实关键在于“谁”能修改核心模块的代码。是哪个固定的开发者吗?你,还是我?

其实都不是。是具备核心模块全部知识的开发者。具备核心模块全部知识的开发者就有能力修改核心模块。

如果不具备核心模块的全部知识,则需要通过外部获取并学习,之后就可以对核心模块进行修改了。

所以,完整的优化步骤:

  1. (若不具备核心模块知识)学习核心模块知识(通过文档、源码、口口相传?等方式)。
  2. 使用核心模块知识,整理代码(设计、重构等)
  3. 重构/整理完成。系统更可控(明确代码与功能的映射关系),且不具备核心模块知识的其他开发人员也可以可控地修改代码。

1)学习核心模块知识

在这里插入图片描述
可以通过各种方式,学习核心模块知识。具备核心模块知识的开发人员才能理解核心模块中的各种机制与复杂,才有能力进行相关内容的修改和重构。

知识不仅包括技术方面的知识,还包括业务知识(业务知识在很多时候都相当重要)。

2)使用核心模块知识整理代码

在这里插入图片描述
吸收完核心模块知识的开发人员,就有能力对核心模块中的混乱部分进行整理了。

在核心模块中,整理代码与功能,使其一一对应(满足单一职责)。

3)重构/整理完成

在这里插入图片描述
重构/整理完成后,每个功能与代码都能清晰地对应起来。仔细观察也可以发现,图中的开发人员现在并没有携带核心模块知识。这也代表:现在不了解核心模块知识的开发人员也可以可控、并行地修改功能(feature1-feature5)了。

重构时另外要注意的事情

一定要有测试层这​层做保障,利用测试拦截与预期不符的错误重构操作。

若测试失败后,代码应该能够回滚至上一版本。最起码先保证系统不会更坏,再思考向前一步。

重构尽可能小步走,这样回滚和测试都会更稳健。

2 其他不太优雅的方案

1)记录法

梳理过部分逻辑后,通过文档或注释记录下来代码与功能的映射关系。适用于发散式变化与霰弹式修改。

总结

单一职责是解决发散式变化和霰弹式修改的利器。

重构时要注意一定要有测试,否则对系统的影响很大,风险完全不可控。风险与收益也不成比例。

出现类似问题时,若不容易重构,可以使用记录法暂时缓解其产生的副作用。

内容还感兴趣吗?公众号中会有更多相关内容持续更新哦
在这里插入图片描述

后记

其实今天的内容也算老生常谈了,很多技术博客和公众号都聊过。今天在这里画画图,让大家更容易理解和记忆。

发散式变换、霰弹式修改的关系是很早之前就有的一个灵感,其实就是上面单一职责里面那个五条线缠在一起的图,当时的脑中有一个动图,好像一堆绳子缠起来又解开的样子,今天才刚刚把它和单一职责关联起来。

这也和单一职责的定义呼应了:一个类应该只有一个发生变化的原因

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

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

相关文章

linux打包流程

因为linux有俩个python版本,我们需要切换到python3这个版本,默认是python 2.7 alias pythonpython3 切换到python3 再次执行:python -V 显示出python的版本了,然后查看pip的配置,我们打包里面需要的第三方需要放到pip…

【C#进阶】简单数据结构类

简单数据结构类 文章目录 1、Arraylist1、ArrayList的本质2、声明3、增删查改4、装箱拆箱思考 背包售卖 2、Stack1、Stack的本质2、声明3、增取查改4、遍历思考 计算一个数的二进制 3、Queue1、Queue的本质2、声明3、增取查改4、遍历思考 每隔一段时间打印一条消息 4、Hashtab…

腾讯共享WiFi项目的加盟方式有哪些?

在这个互联互通的时代,共享经济的浪潮正以前所未有的力量席卷全球,而腾讯作为中国互联网巨头之一自然不会错过这场盛宴。其推出的腾讯共享WiFi项目自问世以来就备受瞩目,它不仅为用户提供便捷的上网服务,更为创业者打开了一个全新…

ModuleSim 仿真找不到模块 module is not defined

提示如下: # vsim -t 1ps -L altera_ver -L lpm_ver -L sgate_ver -L altera_mf_ver -L altera_lnsim_ver -L cycloneive_ver -L rtl_work -L work -voptargs""acc"" pulse_generator_tb # Start time: 14:26:25 on May 10,2024 # ** Note: (…

【全部更新】2024数维杯A题完整成品代码文章思路结果分享

A题 多源机会信号建模与导航分析 摘要 全球卫星定位系统(GPS)虽广泛应用于全球定位与导航,但其在室内、隧道以及建筑密集区等复杂环境中的有效性受限。为解决这一局限性,本研究探讨了一种基于机会信号的自主定位导航方法。 机会信…

一文看懂第三方支付账户体系

什么是账户? 账户是根据会计科目设置的,具有一定格式和结构,用于分类反馈会计要素增加变动情况及其结果的载体。设置账户是会计核算的重要方法之一。 同会计科目分类相对应,账户按其提供的信息详细程度和统驭关系不同分为总账账户…

ICRA 2024 成果介绍:基于 RRT* 的连续体机器人高效轨迹规划方法

近来,连续体机器人研究受到越来越多的关注。其灵活度高,可以调整形状适应动态环境,特别适合于微创手术、工业⽣产以及危险环境探索等应用。 连续体机器人拥有无限自由度(DoF),为执行空间探索等任务提供了灵…

sssadsa

目录 Baidu Comate的功能安装流程功能特性 代码生成代码解释代码补充代码注释智能问答 总结 Baidu Comate: 智能编程助手 在人工智能的驱动下,开发者的编程体验正发生天翻地覆的变化。技术的革新和突破带来的是更智能、高效的工具。Baidu Comate智能代码助手&…

【Vue】Vue的核心

目录 计算属性-computed插值语法实现methods实现计算属性实现使用使用总结: 监视属性-watch监视的两种写法:深度监视备注: computed和watch之间的区别 绑定样式class样式绑定字符串写法数组写法对象写法 style样式绑定对象式1对象式2数组式 条…

汗之谜语,流产之哀:肾合唤醒生命花园的璀璨绽放

在这个疾驰的时代洪流中,女性宛若四季更迭间绚烂绽放的花朵,她们在风雨的锤炼与暖阳的抚慰下,演绎着生命的绚烂篇章。但当这份细腻柔美的内在花园偶遇冷冽寒潮,诸如汗水的异常涌动与生命的意外流失,就如同春暖花开之际…

Wallace树乘法器及Verilog实现

一、Wallace树乘法器 Wallace树乘法器就是将多个部分积进行分组,每三个一组,最后如果剩下的部分积个数不够三个的不做处理,然后将各组的部分积进行相加得到和以及进位信息,直到最终只剩下两行部分积,相加后得到最终结…

界面组件DevExpress Reporting中文教程 - 标记(可访问)PDF导出增强

DevExpress Reporting是.NET Framework下功能完善的报表平台,它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表。 可访问性支持在DevExpress这里仍然是一个高优先…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 5月11日,星期六

每天一分钟,知晓天下事! 2024年5月11日 星期六 农历四月初四 1、 央行新信号:统筹研究消化存量房产和优化增量住房的政策措施。 2、 民政部等七部门规范养老机构预收费:预收周期不得超12个月。 3、 气象局:南方将迎新…

未来相遇过去:博物馆藏品管理平台的科技革新之旅

引言: 尊重历史,意味着保护其实体的载体。在博物馆这个时间的容器中,每一件藏品都承载着人类文明的印记,它们是历史的低语,是过去对现在的细语。在这篇文章中,我将带您走进博物馆的幕后,探究藏品…

软件测试之 性能测试 性能测试基础指标 Loadrunner、Jmeter等工具

你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github gitee 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 想看更多 那就点个关注吧 我会尽力带来有趣的内容 本文档基于 https://www.bilibili.com/video/BV1wC4y1Y…

安全 | 开源入侵防御系统 Snort

目录 Snort 概要 入侵预防系统模式 数据包记录器和嗅探器模式 网络安全学习路线 (2024最新整理) 学习资料的推荐 1.视频教程 2.SRC技术文档&PDF书籍 3.大厂面试题 特别声明: Snort 概要 Snort 概要 是世界上最重要的开源入…

【深度学习】Diffusion扩散模型原理解析1

1、前言 diffusion,这几年一直很火的模型,比如这段时间在网上的文生图大模型——Stable diffusion。就是以diffusion作为基底模型,但由于该模型与VAE那边,都涉及了较多了概率论知识,实在让人望而却步。所以&#xff0…

如何对团队成员进行六西格玛管理的培训?

在现代企业中,六西格玛管理已成为提升产品质量、减少浪费、提高生产效率的重要工具。然而,要想充分发挥六西格玛管理的优势,必须拥有一支熟练掌握这一方法的团队。因此,对团队成员进行六西格玛管理培训至关重要。具体步骤如深圳天…

【话题】你用过最好用的AI工具有那些

大家好,我是全栈小5,欢迎阅读小5的系列文章,这是《话题》系列文章 目录 背景一、C知道二、CSDN工具集三、AI工具的普及与受欢迎程度四、AI工具的实际应用与影响五、总结与展望文章推荐 背景 探讨人们在使用AI工具时,最喜欢的和认…

【JS 的数据类型】

JS 的数据类型 基本数据类型 js有8种基本数据类型,分别为:undefined、number、Object、null、Symbol、Boolean、String、BigInt; 其中Symbol和BigInt是ES6新增的数据类型: ● Symobol代表独一无二的值,可以用来代表对…