与软件复杂性的永无止境的战斗
本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《与软件复杂性的永无止境的战斗》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~

什么是复杂性?
最近读完了《软件设计哲学》,第二章探讨了软件复杂性的话题。
《软件设计哲学》一书实际定义了复杂性:
“复杂性是指与软件系统的结构相关的任何使其难以理解和修改的事物。”
换句话说,复杂性可以有多种形式,并且不一定与性能有任何关系,你的代码可以是高性能的但仍然很复杂
我想在本文中分享本书中的一些关键定义和见解。但首先,让我们想象一个您可能已经经历过的常见情况......
一个简短的恐怖故事
让我们深入探讨一个你们中的许多人可能经历过或将要经历的恐怖故事。
它从一个简单的 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
- 上一篇
- OPPO、vivo、小米、联想应用商店 64 位适配率达 99.1% 以上,8 月 31 日完全淘汰 32 位 App
- 下一篇
- 了解 Java 中的模式匹配
-
- 文章 · 前端 | 34秒前 |
- WebGL3D渲染入门指南详解
- 480浏览 收藏
-
- 文章 · 前端 | 8分钟前 |
- HTML表格压缩传输方法有哪些
- 306浏览 收藏
-
- 文章 · 前端 | 12分钟前 |
- CSSsticky定位的实用场景解析
- 178浏览 收藏
-
- 文章 · 前端 | 17分钟前 |
- JavaScriptIoC容器依赖注入原理详解
- 484浏览 收藏
-
- 文章 · 前端 | 19分钟前 |
- HBuilder运行HTML方法及步骤详解
- 451浏览 收藏
-
- 文章 · 前端 | 20分钟前 |
- JavaScript绑定this的正确方法详解
- 266浏览 收藏
-
- 文章 · 前端 | 21分钟前 |
- XSS攻击防范技巧与JS安全编码方法
- 331浏览 收藏
-
- 文章 · 前端 | 25分钟前 | cors 浏览器兼容性 MIME类型 自动播放策略 HTML音频无法播放
- 音频无法播放原因及解决方法
- 284浏览 收藏
-
- 文章 · 前端 | 30分钟前 |
- CSS实现sticky定位技巧分享
- 298浏览 收藏
-
- 文章 · 前端 | 31分钟前 |
- 浮动与inline-block结合使用方法
- 421浏览 收藏
-
- 文章 · 前端 | 38分钟前 | CSS background-size object-fit 图片比例 图片拉伸变形
- 图片拉伸变形怎么解决?object-fit保比例
- 203浏览 收藏
-
- 文章 · 前端 | 43分钟前 |
- CSS动画与过渡结合使用技巧
- 495浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3210次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3424次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3453次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4561次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3831次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览

