Clean Code 是一套纪律化的代码编写框架,目标是让代码传达意图、减少意外,并欢迎变更。官方说明指出,可在编写新代码、审查拉取请求(pull request)、重构遗留系统或提供代码质量建议时应用这些原则。
【核心原则】 代码被阅读的次数远多于被编写的次数,因此应针对读者进行优化。读与写的比例超过 10:1,每一次命名、函数边界和格式决策,要么增加清晰度,要么增加成本。干净的代码读起来像写得好的散文:名称揭示意图,函数一步一步讲故事,并遵循“童子军规则”——总是让代码比你发现它时更干净。
【评分标准】 目标为 10/10。对任何代码按下列原则评定 0-10 分,并报告当前得分以及达到 10/10 所需的具体改进。
- 9-10:名称揭示意图,每个函数只做一件事,错误处理一致,测试干净且全面。
- 7-8:基本干净,有轻微的命名歧义或少数多用途函数;测试可能缺少边界情况。
- 5-6:喜忧参半——好的模式与不清晰的名称、重复逻辑或不一致的错误处理并存。
- 3-4:冗长的多用途函数、误导性的名称、测试差或缺失。
- 1-2:几乎无法阅读——魔法数字、隐晦的缩写、没有结构、没有测试。
【六大纪律】
-
有意义的命名:名称应揭示意图、避免误导,让代码读起来像散文。若名称需要注释解释,则名称是错的。名称应回答它为何存在、做什么、如何使用。不使用编码、前缀或类型信息(不用匈牙利命名法);单字母仅用于极小作用域的循环计数器。类是名词,方法是动词。同一概念用一个词,不要混用 fetch、retrieve 和 get。作用域越长,名称应越长越具描述性。可自由重命名,IDE 使这变得轻而易举。
-
函数:函数只做一件事、处于一个抽象层级,参数为零到两个。当它做两件事时才拆分,而不是依据行数:一个签名小、背后只做一件工作的长函数是一个深模块。要点包括:自顶向下规则(step-down rule),代码自上而下阅读,每个函数调用下一抽象层级;参数数量零最好、一个可以、两个可接受、三个以上需要理由;标志参数是坏味,说明函数做两件事,应拆分;命令查询分离(Command-Query Separation),改变状态或返回值,绝不两者兼有;当代码块有自己的名称和职责时提取;无隐藏副作用,名称必须说出全部真相。
-
注释与格式:注释是未能用代码表达自己的失败。必要时注释解释“为什么”,绝不解释“什么”。注释会腐烂——代码变而注释常常不变,产生比没有更糟的文档。最好的注释是命名良好的提取函数。可接受的注释包括:法律头、TODO、公共 API 文档、真正的“为什么”解释。被注释掉的代码和日志式注释应删除,版本控制记得住。格式上,概念之间垂直留白,概念内部垂直紧凑,变量在靠近使用处声明。采用报纸隐喻:高层函数在文件顶部,细节在下。团队格式应一次决定并用 Prettier、Black、gofmt 等自动化。
-
错误处理:错误处理是与业务逻辑分开的关注点。使用异常而非返回码,为每个异常提供上下文,绝不返回或传递 null。先写 try-catch,它定义了事务边界。优先使用非受检异常,受检异常违反开闭原则。按调用者需求而非失败类型定义异常类。不返回 null(用空集合、Optional 或抛出异常),也不传递 null。特例/空对象模式:返回具有默认行为的对象而非 null。
-
单元测试:测试是一等代码,用与生产代码相同的纪律保持干净。脏测试比没有测试更糟——它们成为拖慢每次变更的负担。要点包括:TDD 三定律(先写失败测试;只写足够失败的测试;只写足够通过的代码);每个测试一个概念——一个逻辑断言,未必是一个 assert;F.I.R.S.T.(快速、独立、可重复、自验证、及时);构建领域特定的测试语言,即读起来像 DSL 的辅助方法;像重构生产代码一样随时重构测试代码。
-
代码坏味与启发式:坏味是深层设计问题的表面指标,快速识别并施加有针对性的重构,而非模糊的“清理”。要点包括:函数坏味(参数过多、输出参数、标志参数、死函数);通用坏味(重复、错误的抽象层级、依恋情结、魔法数字);测试坏味(覆盖不足、被跳过的测试、未测试的边界条件和失败路径)。以小而可测试的步骤重构——绝不同时重构和添加功能。遵循童子军规则。
【常见错误】官方列出了若干常见错误及其修复方式,包括:使用缩写名称(写时省几秒,读时费几小时,应使用完整描述性名称);“聪明”的一行代码(写时惊艳,调试时不可能,应展开为可读的命名步骤);用注释代替重构(注释会腐烂,代码才是真相,应提取命名良好的函数);捕获通用异常(连同预期错误一起吞掉 bug,应捕获特定异常,让其余传播);不为错误路径写测试(快乐路径正常,边界情况崩溃,应测试每个分支、边界和失败模式);过早优化(为微小收益模糊意图,应先保持干净,再优化已测量的瓶颈);上帝类(一个 2000 行类做所有事,应应用 SRP 按职责拆分);无测试重构(没有回归安全网,应先写特征测试);不一致的约定(每个文件像不同代码库,应商定风格并用 linter 和 formatter 强制执行);到处返回 null(空检查像病毒般扩散,应用 Optional、空集合或空对象)。
【快速诊断】官方提供了一组诊断问题及行动,例如:能否不读函数体就理解每个函数(否则重命名以描述其功能);每个函数是否只做一件事(否则将每项独立工作提取为命名函数);是否零注释掉的代码块(否则删除,版本控制有历史);错误处理是否与业务逻辑分离(否则提取处理器,用异常而非返回码);每个类是否单一职责(否则拆分为聚焦且命名良好的类);每个公共方法是否有测试(否则在进一步修改前添加测试);测试名称是否描述行为(否则重命名为 shouldDoXWhenY);重复是否低于 3 次(否则提取共享函数或模块);魔法数字是否已命名为常量(否则提取描述性常量);所有测试是否在 10 秒内运行(否则 mock 外部依赖,拆分集成测试)。
【参考文件】官方列出多个参考文件:naming-conventions.md(揭示意图的名称、避免误导、类与方法命名、前后对比示例);functions-and-methods.md(每个函数一项工作、参数数量、命令查询分离、自顶向下规则、副作用);comments-formatting.md(好注释与坏注释、报纸隐喻、垂直格式、团队规则);error-handling.md(异常优于返回码、null 处理、特例模式、包装第三方 API);testing-principles.md(TDD 定律、F.I.R.S.T. 原则、干净的测试模式、测试可读性);code-smells.md(按类别组织的全面坏味目录,附有针对性的重构)。
【延伸阅读】基于 Robert C. Martin 关于软件工艺的著作:Robert C. Martin 的《Clean Code: A Handbook of Agile Software Craftsmanship》《The Clean Coder: A Code of Conduct for Professional Programmers》《Clean Architecture: A Craftsman's Guide to Software Structure and Design》,以及 Martin Fowler 的《Refactoring: Improving the Design of Existing Code》。
【关于作者】Robert C. Martin(“Uncle Bob”)自 1970 年开始编程,是敏捷宣言的合著者,创立了 Uncle Bob Consulting 和 Clean Coders。他的著作——Clean Code、The Clean Coder、Clean Architecture 和 Clean Agile——塑造了一代开发者对代码质量的思考,其核心立场是:唯一能快速前进的方式就是做得更好。
本页面未提供该技能的具体安装命令、价格或收费信息。