与软件复杂性的永无止境的战斗
本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《与软件复杂性的永无止境的战斗》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~
什么是复杂性?
最近读完了《软件设计哲学》,第二章探讨了软件复杂性的话题。
《软件设计哲学》一书实际定义了复杂性:
“复杂性是指与软件系统的结构相关的任何使其难以理解和修改的事物。”
换句话说,复杂性可以有多种形式,并且不一定与性能有任何关系,你的代码可以是高性能的但仍然很复杂
我想在本文中分享本书中的一些关键定义和见解。但首先,让我们想象一个您可能已经经历过的常见情况......
一个简短的恐怖故事
让我们深入探讨一个你们中的许多人可能经历过或将要经历的恐怖故事。
它从一个简单的 CRUD 任务管理应用程序开始。代码干净、模块化且易于维护。开发团队很高兴,系统对于最初的客户来说运行得很好。
当销售团队将系统出售给一家大公司时,问题就开始了,声称它具有日历集成、电子邮件通知和令人惊叹的报告生成器。销售完成后,这些功能必须快速实施。
日历集成: 团队必须与 Google 日历和 Outlook 集成。不同的开发人员实施了解决方案,导致方法不一致。
电子邮件通知:接下来添加了电子邮件通知。一位开发人员使用特定的库,而另一位开发人员创建了自定义解决方案。混合的方法使代码变得混乱。
报告生成器: 对于报告生成器,开发人员使用了各种技术:PDF、Excel 导出和交互式仪表板。缺乏统一的方法使维护成为一场噩梦。
不断增长的复杂性:每个功能都是独立快速开发的,导致功能之间存在依赖关系。开发人员开始创建“快速修复”以使一切正常运行,从而增加了系统的复杂性和耦合性。
软件开发不是凭空发生的;各种内部和外部因素都会对其产生影响。我们都曾经历过或将会经历过这样的情况。
结局的开始
然后问题就开始了:
- 系统某一部分的变化意外地影响了其他部分。
- 小改动需要修改许多其他文件,使得估计变得困难。
- 月复一月,代码变得越来越难以理解,通常通过反复试验来修复。
- 生产力下降,每个人都害怕维护任务。
- 不可避免地呼吁“我们需要重构。”
- 某些任务只能由特定的开发人员处理(经典)
- 随着时间的推移,曾经编写精美且文档齐全的软件变成了火车残骸。
命名症状
很明显,我们现在拥有一个复杂的系统。
现在让我们“剖析”这种复杂性,以便更容易识别和减轻它。
嗯,“缓解”的意思是:
“减轻严重性、严重性或痛苦;减轻。”
我相信复杂性通常是代码所固有的。有些事情本质上是复杂的。作为开发人员,您的角色不仅仅是创建计算机可以高效执行的代码,还要创建未来的开发人员(包括未来的您)可以使用的代码。
“控制复杂性是计算机编程的本质。”
— 布莱恩·科尼汉
上述书籍的作者指出,复杂性通常以三种方式表现出来,我们将在这里进行探讨。
改变放大
当看似简单的更改需要在许多不同的地方进行修改时,就会发生更改放大。
例如,如果产品负责人请求“优先级”或“完成日期”字段,并且您的实体紧密耦合,那么您需要进行多少更改?
认知负荷
认知负荷是指开发人员完成任务所需的知识量和时间。
想象一下这样的场景:一位新开发人员加入了团队,他被指派修复报告生成器中的错误。为了完成此任务,开发人员需要:
- 了解不同的日历集成(Google 和 Outlook)。
- 掌握电子邮件通知的不同方法。
- 浏览报告生成器的碎片代码,处理 PDF、Excel 和仪表板。
- 整合这些不同的技术和风格来查找并修复错误。
这是典型的“无法估计”场景,任务可能需要 1 分或 8 分——最好掷 D20 并做出相应的反应。
未知的未知
未知的未知是当你不知道你不知道的事情时。
这是复杂性最糟糕的表现,因为你可能会改变不应该改变的东西,导致一切都崩溃。
示例:开发人员修改了电子邮件发送代码以添加新通知,但没有意识到这会影响依赖于该函数的报告生成器。这给客户带来了重大问题,体现了紧急复杂性的最坏形式。
复杂性的原因
看完恐怖故事和三个主要症状,让我们看看是什么导致了复杂性。
1. 依赖关系
依赖关系在软件中是必不可少的,并且无法完全消除。它们允许系统的不同部分相互作用并一起运行。然而,如果管理不当,依赖关系会显着增加复杂性。
定义:
当代码无法单独理解或修改时,就存在依赖关系,需要考虑或修改相关代码。
依赖项类型:
- Direct: 模块A直接依赖模块B。
- 传递性: 模块 A 依赖于模块 B,模块 B 又依赖于模块 C。
- 循环: 模块A、B、C以循环方式相互依赖。
2. 默默无闻
当重要信息不明显时,就会出现模糊性。这可能会使代码库难以理解,从而导致认知负荷增加和未知未知的风险。
定义:
当重要信息不明显时,就会出现模糊性。
晦涩难懂的例子:
- 不良命名:名称不明确的变量和函数。
- 隐藏的副作用:执行意外操作的方法。
- 全局状态: 过度使用全局变量。
- 深度继承: 行为分布在类层次结构中的多个级别。
请记住:复杂性是渐进的
- 复杂性很少是由单个“错误”或错误的决定引起的。
- 随着时间的推移,错误的决策和依赖性会“缓慢”地增加复杂性。
因为它是增量的,所以很容易想到,“就这一次,没关系。”但积累起来后,仅修复一两个依赖项并不会产生太大影响。
“软件工程中的一切都是权衡。”
——我不记得作者了
结论
我可以写很多你可能已经在互联网上看到的关于如何避免复杂性的规则、策略和框架:SOLID、设计模式、YAGNI、KISS 等。
但是,您可以将它们统一为一个指导原则(如“务实的程序员”中提到的。): “我正在实现的内容容易更改吗?” 如果答案是否定的,那么您可能会增加复杂性。
确保您的代码易于更改可以简化维护,减少开发人员的认知负担,并使系统更具适应性且不易出错。
谢谢你!
到这里,我们也就讲完了《与软件复杂性的永无止境的战斗》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

- 上一篇
- OPPO、vivo、小米、联想应用商店 64 位适配率达 99.1% 以上,8 月 31 日完全淘汰 32 位 App

- 下一篇
- 了解 Java 中的模式匹配
-
- 文章 · 前端 | 12分钟前 |
- WebWorkers技巧:提升JavaScript性能
- 491浏览 收藏
-
- 文章 · 前端 | 12分钟前 |
- JavaScriptArray.find方法使用技巧大全
- 316浏览 收藏
-
- 文章 · 前端 | 20分钟前 |
- JavaScript中Map和Set的区别与应用
- 366浏览 收藏
-
- 文章 · 前端 | 21分钟前 | 正则表达式 addEventListener 客户端验证 服务器端验证 即时反馈
- JavaScript表单验证实用攻略
- 190浏览 收藏
-
- 文章 · 前端 | 30分钟前 |
- JavaScript中如何使用AJAX发送请求?
- 118浏览 收藏
-
- 文章 · 前端 | 31分钟前 |
- JavaScript中null和undefined的区别详解
- 247浏览 收藏
-
- 文章 · 前端 | 33分钟前 | blob URL.createObjectURL fetchAPI dataUrl a标签download属性
- JavaScript文件下载实现方法与技巧详解
- 406浏览 收藏
-
- 文章 · 前端 | 41分钟前 |
- JavaScriptasync/await使用技巧详解
- 326浏览 收藏
-
- 文章 · 前端 | 51分钟前 | JavaScript 通知 订阅 观察者模式 取消订阅
- JavaScript观察者模式实现详解
- 218浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- JavaScript中IntersectionObserverAPI的使用技巧
- 323浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- JavaScriptShadowDOM使用技巧与示例
- 409浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- AI Make Song
- AI Make Song是一款革命性的AI音乐生成平台,提供文本和歌词转音乐的双模式输入,支持多语言及商业友好版权体系。无论你是音乐爱好者、内容创作者还是广告从业者,都能在这里实现“用文字创造音乐”的梦想。平台已生成超百万首原创音乐,覆盖全球20个国家,用户满意度高达95%。
- 17次使用
-
- SongGenerator
- 探索SongGenerator.io,零门槛、全免费的AI音乐生成器。无需注册,通过简单文本输入即可生成多风格音乐,适用于内容创作者、音乐爱好者和教育工作者。日均生成量超10万次,全球50国家用户信赖。
- 13次使用
-
- BeArt AI换脸
- 探索BeArt AI换脸工具,免费在线使用,无需下载软件,即可对照片、视频和GIF进行高质量换脸。体验快速、流畅、无水印的换脸效果,适用于娱乐创作、影视制作、广告营销等多种场景。
- 13次使用
-
- 协启动
- SEO摘要协启动(XieQiDong Chatbot)是由深圳协启动传媒有限公司运营的AI智能服务平台,提供多模型支持的对话服务、文档处理和图像生成工具,旨在提升用户内容创作与信息处理效率。平台支持订阅制付费,适合个人及企业用户,满足日常聊天、文案生成、学习辅助等需求。
- 16次使用
-
- Brev AI
- 探索Brev AI,一个无需注册即可免费使用的AI音乐创作平台,提供多功能工具如音乐生成、去人声、歌词创作等,适用于内容创作、商业配乐和个人创作,满足您的音乐需求。
- 18次使用
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览
-
- UI设计中为何选择绝对定位的智慧之道
- 2024-02-03 501浏览