垃圾代码(意大利面条式代码、混乱、big ball of mud)——是杂乱无章、结构不良的源代码,难以阅读、维护和修改,且有破坏功能的风险。该术语描述了依赖关系交织、缺乏统一架构和违反干净代码原则的代码库。根据 TIOBE Index,2025 的数据,具有高技术水平技术债务的项目比组织良好的代码库平均需要 4 倍 的时间来添加新功能。
要点
垃圾代码(也称意大利面条式代码、混乱、big ball of mud)——是对失去结构、变成混乱依赖关系网的代码库的比喻。在这种代码中,每一处更改都会破坏其他部分,添加新功能变成一项危险的任务。
在 移动开发 中,垃圾代码尤为关键:建立在「混乱」之上的应用程序开始变慢,在旧设备上崩溃,并且难以通过代码审查。没有架构的 iOS 项目可能因不稳定而无法通过 App Review。
根据 Stripe 的数据,开发人员花费高达 42% 的工作时间来阅读和理解现有代码。在存在垃圾代码的项目中,这一指标超过 60%,这使得开发效率极其低下。
Spaghetti code(意大利面条式代码)——最古老的术语,出现于 20 世纪 70 年代。它描述了具有混乱控制流的代码,类似于缠绕在一起的意大利面条。
Big ball of mud(大泥球)——由 Brian Foot 和 Joseph Yoder 在 1997 年引入的术语,用于描述没有明确架构、混乱「生长」的系统。
垃圾代码 减慢了新功能推向市场的速度。团队的时间不是用于创造价值,而是用于尝试理解现有代码的工作方式并不破坏任何东西。
根据 McKinsey 的数据,低代码质量的公司比高代码质量的公司多花费 20-40% 的产品维护费用,新功能推出速度也低 2-3 倍。
识别 垃圾代码可以通过一系列客观特征进行,其中一些可以自动测量。匹配的特征越多——问题越严重。
在 行业 中使用诸如 Halstead Complexity、Maintainability Index 和 Technical Debt Ratio 等代码质量指标。了解这些指标有助于客观评估代码库的状态。
最常见 的垃圾代码特征——重复的代码块。开发人员不是提取公共函数,而是将代码从一处复制到另一处,仅做最少的修改。
正常的 水平 重复率不超过 5%。如果重复率超过 15%——这是一个严重信号。Simian 和 PMD Copy Paste Detector 等工具有助于自动检测复制粘贴。
方法 超过 100 行——垃圾代码的明显特征。这样的方法通常做了太多事情,违反了单一职责原则(Single Responsibility)。
超过 1000 行代码的 类 同样存在问题。它们包含不相关的功能,这使测试、理解和修改代码变得困难。
圈 复杂度(Cyclomatic Complexity)——显示代码中独立路径数量的指标。超过 15 的值被认为有问题。
复杂度 超过 30 的方法——「灾难区域」。它们包含太多分支,无法在没有深入分析的情况下进行测试或理解。
垃圾代码 不会「自行」出现——它始终是团队中特定流程和决策的结果。了解原因可以在未来防止其出现。
根据 JetBrains Developer Ecosystem 2024 的数据,67% 的开发人员承认由于时间不足而写出了比他们能力更差的代码。这是技术债务积累的主要原因。
最常见 的原因——紧迫的截止日期。团队写出「应付了事」的代码,只为赶上截止日期。重构、测试和代码审查被推迟到「以后」。
问题在于 「以后」 永远不会到来——在下一个 Sprint 中会出现新的截止日期,技术债务像雪球一样越滚越大。
没有 代码审查,每个开发人员都有自己的风格、使用自己的模式并留下自己的「陷阱」。随着时间的推移,代码库失去了统一性。
根据 SmartBear 2024 的研究,对每个拉取请求实施 强制 代码审查的团队在生产中的缺陷少 60%。
如果 项目开始时没有清晰的架构,垃圾代码是不可避免的。最初的「快速解决方案」奠定了基础,之后很难在上面构建出高质量的东西。
在 移动 开发中,架构选择(MVC、MVP、MVVM、Clean Architecture)应该是在开始编写代码之前做出的有意识决定,而不是演化的结果。
对抗 垃圾代码需要系统性的方法和整个团队的纪律。没有任何单一工具或实践可以解决这个问题——需要一系列措施。
主要 原则 ——在编写阶段就防止垃圾代码,而不是事后修复。预防总是比重构现有的「混乱」更便宜。
统一 的代码风格是防止垃圾代码的基础。编码标准(Code Style)应该文档化并由 linter 自动检查。
对于 iOS,使用 SwiftLint;对于 Android,使用 Ktlint 和 Detekt。在配置文件中设置规则可以自动拒绝违反标准的拉取请求。
重构 ——不是修复错误,而是在不改变行为的情况下改善代码结构。它应该是开发过程中的常规部分,而不是一个单独的项目。
建议 分配 每个 Sprint 20% 的时间用于重构和偿还技术债务。这可以防止「混乱」的积累并在长期内保持团队的速度。
每个 拉取请求都应该由至少一位开发人员进行审查。代码审查不仅发现错误,还发现架构违规、风格问题和潜在的垃圾代码来源。
良好的 实践 ——一份代码审查检查清单,包括检查复制粘贴、方法长度、圈复杂度和测试覆盖率。没有检查清单,审查者会漏掉多达 50% 的问题。
现代 代码分析工具可以自动检测垃圾代码、衡量技术债务和控制质量。将这些工具集成到 CI/CD 管道中可以确保持续监控。
建议 使用 至少一个静态分析器和一个指标测量工具。此外,还可以连接一个聚合代码质量数据的平台。
根据 SonarSource 的数据,使用静态分析的团队在实施后的第一个季度就能将生产中的错误数量减少 30%。
CodeClimate 和 Codacy ——聚合代码质量指标、跟踪动态并显示「热点」(技术债务最大的文件)的平台。
对于 Android 项目,Detekt 提供了 100 多条内置分析规则,包括检查圈复杂度、方法长度和代码重复。
常见问题
在一个发展了数年的大型项目中 完全 消除垃圾代码实际上是不可能的。目标不是「干净代码」,而是不阻碍开发的可控水平的技术债务。
从 评估 当前状态开始:运行静态分析器,获取指标并确定最有问题的模块。然后系统地、一个 Sprint 接一个 Sprint 地重构最关键的部分。
没有 测试 的重构不是重构,而是盲目重写代码。没有测试就无法确认行为是否发生变化。在开始重构遗留代码之前,务必先用特征测试覆盖它。
为每个拉取请求实施 关卡控制:linter 自动检查、通过代码审查、测试覆盖率不低于设定阈值。任何代码在通过所有关卡之前不能进入主分支。
用金钱展示技术债务的 成本:多少小时浪费在维护垃圾代码上,因此产生了多少错误,如何减慢了新功能的推出。SonarQube Technical Debt Ratio 指标是令人信服的论据。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。