Searching...
简体中文
English
Español
简体中文
Français
Deutsch
日本語
Português
Italiano
한국어
Русский
Nederlands
العربية
Polski
हिन्दी
Tiếng Việt
Svenska
Ελληνικά
Türkçe
ไทย
Čeština
Română
Magyar
Українська
Bahasa Indonesia
Dansk
Suomi
Български
עברית
Norsk
Hrvatski
Català
Slovenčina
Lietuvių
Slovenščina
Српски
Eesti
Latviešu
فارسی
മലയാളം
தமிழ்
اردو
Clean Code

Clean Code

A Handbook of Agile Software Craftsmanship
by Robert C. Martin 2008 464 pages
Programming
Computer Science
Technology
11 minutes

重点摘要

1. 编写可读且可维护的干净代码

唯一有效的代码质量衡量标准:每分钟的WTF次数

可读性至关重要。 干净的代码应易于其他开发人员理解。它应简单、优雅且无杂乱。努力编写无需大量注释即可清晰表达意图的代码。使用有意义的变量和函数名称,保持函数小而专注,并逻辑地组织代码。

可维护性使演变成为可能。 难以更改的代码会成为负担。设计灵活且模块化的代码,以适应不断变化的需求。遵循DRY(Don't Repeat Yourself)和SOLID等原则,创建松耦合、高内聚的系统。无情地重构以在不改变行为的情况下改进代码结构。

干净的代码有回报。 虽然编写干净代码需要更多的前期努力,但从长远来看,它节省了大量时间和麻烦。干净的代码更易于调试、扩展和维护。它使开发人员工作更高效,并减少在更改过程中引入错误的风险。将编写干净代码作为开发实践的核心部分。

2. 遵循有意义的命名约定

变量、函数或类的名称应回答所有重要问题。它应告诉你为什么存在、做什么以及如何使用。

使用意图揭示的名称。 选择清晰传达变量、函数和类目的和行为的名称。避免单字母名称或难解的缩写。使用易于搜索的可发音名称。例如:

  • 不好:d(以天为单位的经过时间)
  • 好:elapsedTimeInDays

保持一致和精确。 在整个代码库中使用一致的命名约定。精确以避免歧义——例如,使用有意义的区分,如getActiveAccounts()和getActiveAccountInfo()。避免添加无价值噪音的编码或前缀。类名应为名词,方法名应为动词。

名称长度应匹配范围。 对于范围较大的变量和函数,使用较长且更具描述性的名称。对于小的局部范围,短名称是可以接受的。名称的长度应与其使用范围成比例。优化可读性和在使用上下文中的理解。

3. 保持函数小而专注

函数应做一件事。它们应做好这件事。它们应只做这件事。

小即美。 函数应小——通常5-10行长。它们应能在一个屏幕上显示并立即被理解。将代码提取到命名良好的辅助函数中,而不是编写长而复杂的函数。小函数更易于理解、测试和维护。

做好一件事。 每个函数应有一个明确的目的。如果一个函数在做多件事,将这些提取到单独的函数中。函数做得太多的迹象包括:

  • 多层抽象
  • 多个部分或代码块
  • 大量参数

保持一个抽象层次。 函数内的语句应都在同一抽象层次。不要将高层逻辑与低层细节混合。将低层操作提取到单独的函数中。这通过保持函数专注和概念简单来提高可读性。

4. 练习正确的格式和组织

代码格式是关于沟通,而沟通是专业开发人员的首要任务。

一致的格式很重要。 在整个代码中使用一致的缩进、换行和间距。这提高了可读性并减少了认知负担。与团队达成格式标准并使用自动化工具来强制执行。关键的格式指南包括:

  • 正确的缩进
  • 一致的括号位置
  • 合理的换行
  • 适当的空白

逻辑地组织代码。 将相关代码分组在一起,分隔不相关的代码。使用空行在逻辑部分之间创建“段落”分隔。将相关函数放在一起。使文件专注于单一概念或组件。适当时将大文件拆分为更小、更专注的文件。

遵循标准约定。 遵循语言和社区的标准约定。这使你的代码对其他开发人员更熟悉和可访问。例如,在Java中:

  • 类名使用PascalCase
  • 方法名使用camelCase
  • 常量使用ALL_CAPS

5. 管理依赖并避免重复

重复可能是软件中所有邪恶的根源。

消除重复。 重复的代码是抽象的错失机会。当你看到重复时,将公共代码提取到可重用的函数或类中。这通过集中逻辑并减少不一致更改的风险来提高可维护性。需要注意的重复类型包括:

  • 相同的代码块
  • 略有变化的相似算法
  • 重复的switch/case或if/else链

仔细管理依赖。 最小化模块之间的依赖以减少耦合。使用依赖注入和控制反转使代码更模块化和可测试。遵循依赖倒置原则——依赖抽象而不是具体实现。这使你的代码更灵活且更易于更改。

使用最少知识原则。 模块不应了解其操作对象的内部。这减少了模块之间的耦合。例如,使用Demeter法则——方法应只调用:

  • 它自己的对象
  • 作为参数传递的对象
  • 它创建的对象
  • 它的直接组件对象

6. 优雅地处理错误

错误处理很重要,但如果它掩盖了逻辑,那就是错误的。

使用异常而不是错误代码。 异常更简洁,不会混乱代码的主逻辑。它们允许将错误处理与正常路径分开。使用异常时:

  • 创建有信息的错误消息
  • 提供上下文
  • 根据调用者的需要定义异常类

不要返回null。 返回null会导致空指针异常,并使代码充满null检查。相反:

  • 对于列表,返回空集合而不是null
  • 使用Null对象模式
  • 在Java中使用Optional或在函数式语言中使用Maybe

首先编写try-catch-finally语句。 在编写可能抛出异常的代码时,先编写try-catch-finally。这有助于定义调用代码的范围和期望。它确保资源在错误场景中也能正确管理和释放。

7. 编写全面的单元测试

测试代码与生产代码同样重要。

遵循TDD的三条法则。 测试驱动开发(TDD)提高代码质量和设计:

  1. 在编写任何生产代码之前编写失败的测试
  2. 仅编写足以展示失败的测试
  3. 仅编写足以通过测试的生产代码

保持测试干净和可维护。 对测试代码应用与生产代码相同的质量标准。定期重构和改进测试代码。结构良好的测试可作为文档,并使生产代码的无畏重构成为可能。

目标是全面的测试覆盖。 编写覆盖边界情况、边界条件和错误场景的测试——不仅仅是正常路径。使用代码覆盖工具识别测试覆盖的空白。记住,100%的覆盖率并不保证无错误代码,但它提供了重构和更改的信心。

8. 持续重构代码

离开营地时比你找到它时更干净。

机会主义地重构。 每当你处理一段代码时,改进代码结构。遵循童子军规则:离开代码时比你找到它时更好。小的、渐进的改进随着时间的推移累积起来,防止代码腐烂。常见的重构技术包括:

  • 提取方法或类
  • 为清晰重命名
  • 简化复杂的条件
  • 消除重复

通过测试安全地重构。 在重构之前始终有一套可靠的测试。进行小的、渐进的更改并频繁运行测试。这使你有信心你的更改不会破坏现有功能。使用自动化重构工具(如果有)以减少引入错误的风险。

在交付价值和重构之间取得平衡。 虽然持续重构很重要,但不要让它阻碍进展。目标是“足够好”而不是完美。将重构工作集中在最有问题或经常更改的代码区域。向利益相关者传达重构的价值,以确保对持续代码改进的支持。

9. 应用面向对象和函数式编程原则

对象将其数据隐藏在抽象后面,并暴露操作该数据的函数。数据结构暴露其数据且没有有意义的函数。

明智地使用面向对象原则。 应用封装、继承和多态等原则,创建灵活、模块化的设计。遵循SOLID原则:

  • 单一职责原则
  • 开放-封闭原则
  • 里氏替换原则
  • 接口隔离原则
  • 依赖倒置原则

利用函数式编程概念。 即使在面向对象语言中,函数式编程技术也能带来更干净的代码:

  • 无副作用的纯函数
  • 不可变数据
  • 高阶函数
  • 函数组合

为问题选择正确的方法。 面向对象和函数式范式各有优缺点。需要建模具有行为的复杂领域时使用面向对象设计。用于数据转换和处理管道时使用函数式方法。许多现代语言支持混合方法,允许你为系统的每个部分使用最佳工具。

10. 仔细考虑并发性

并发是一种解耦策略。它帮助我们解耦完成什么与何时完成。

理解并发挑战。 并发编程引入了复杂性和潜在的微妙错误。常见问题包括:

  • 竞争条件
  • 死锁
  • 丢失信号
  • 内存可见性问题

分离并发问题。 将并发相关的代码与其他代码分开。这使其更易于推理和测试。使用Executors、Futures和Actors等抽象来管理并发,而不是直接处理线程。

偏爱不可变性和纯函数。 不可变对象和纯函数本质上是线程安全的。它们通过避免共享可变状态消除了许多并发问题。当需要可变状态时,使用适当的同步技术,并考虑使用原子变量或并发集合。

Last updated:

评论

4.37 out of 5
Average of 21k+ ratings from Goodreads and Amazon.

《代码整洁之道》因其关于编写可读、可维护代码的原则而广受好评。读者们赞赏书中关于命名、函数和测试的实用建议。尽管书中对Java的关注和一些过于严格的指导方针常被批评,许多人仍认为这是开发者必读的书籍,尽管有些经验丰富的程序员觉得它的实用性较低。书中的案例研究和重构示例受到一些人的赞扬,但也有一些人认为这些内容过于繁琐。总体而言,评论者一致认为这本书在代码质量方面提供了宝贵的见解,即使并非所有建议都普遍适用。

关于作者

罗伯特·塞西尔·马丁,被称为鲍勃大叔,是一位著名的软件工程师和顾问。他提倡敏捷开发方法,并担任Object Mentor Inc.的总裁。马丁在面向对象设计、模式、UML和极限编程方面拥有丰富的专业知识。他与全球客户合作,通过咨询和演讲分享他的知识。1996年至1999年间,马丁担任《C++报告》的主编。他是软件开发社区的知名人物,经常在国际会议和贸易展览会上发表演讲。通过他的书籍和文章,马丁的影响力超越了他的咨询工作,涵盖了软件工艺和最佳实践。

0:00
-0:00
1x
Create a free account to unlock:
Bookmarks – save your favorite books
History – revisit books later
Ratings – rate books & see your ratings
Listening – audio summariesListen to the first takeaway of every book for free, upgrade to Pro for unlimited listening.
🎧 Upgrade to continue listening...
Get lifetime access to SoBrief
Listen to full summaries of 73,530 books
Save unlimited bookmarks & history
More pro features coming soon!
How your free trial works
Create an account
You successfully signed up.
Today: Get Instant Access
Listen to full summaries of 73,530 books.
Day 4: Trial Reminder
We'll send you an email reminder.
Cancel anytime in just 15 seconds.
Day 7: Trial Ends
Your subscription will start on Sep 26.
Monthly$4.99
Yearly$44.99
Lifetime$79.99