CLASS 03 · 2026-02-09 · 规格与设计
代码审查
代码审查是「易于理解」这一品质的直接实践。本讲通过三个「气味」示例,系统介绍良好编码的通用原则:不要重复自己、快速失败、使用好名字、避免全局变量等。
代码审查是什么
代码审查(Code review)是由代码原作者之外的人对源代码进行仔细、系统的研读。
代码审查有双重目的:
- 改进代码:发现 bug、预判潜在 bug、检查代码清晰度。
- 改进程序员:代码审查是程序员彼此学习和教学的重要方式。
审查者不是挑刺的批评家,而是帮助代码变得更好的协作者。
气味示例一:重复、注释与魔术数字
先看一段有「气味」的代码:
// 不好的例子:重复、魔术数字、缺少注释
function area(r: number): number {
return 3.14159265 * r * r;
}
function circumference(r: number): number {
return 2 * 3.14159265 * r;
}
不要重复自己(DRY)
DRY 原则:知识或逻辑只在一个地方表达,不要重复。
重复的代码是安全的隐患——一旦需要修改(例如提高 \(\pi\) 的精度),你必须记得修改每一处,漏改任何一处就会引入不一致的 bug。
在需要的地方写注释
好的开发者审慎地写注释。注释应解释「为什么」而非「是什么」——代码本身已经说明了它在做什么。
快速失败
快速失败(Fail fast):代码应尽早暴露自己的 bug。
例如,如果半径不应为负数,应在函数入口处立即检查并抛出异常,而不是让错误悄悄传播到下游。
避免魔术数字
代码中直接出现的、没有名字的数字常量称为魔术数字(magic numbers)。应将其提取为命名常量:
const PI = 3.14159265;
function area(r: number): number {
if (r < 0) throw new Error("radius must be nonnegative");
return PI * r * r;
}
function circumference(r: number): number {
if (r < 0) throw new Error("radius must be nonnegative");
return 2 * PI * r;
}
每个变量只承担一个职责
不要复用参数,也不要让一个变量在不同位置承担不同含义。变量复用会让读者困惑,也让修改更危险。
气味示例二:命名与排版
// 不好的例子:命名含糊、排版混乱
function f(a: number, b: number): number {
let c=a+b;let d=a-b;return c*d;
}
使用好名字
好的函数名和变量名应该长且能自我描述。f、a、b 这样的名字没有传达任何意图;sumAndProductDifference、width、height 则清晰得多。
用空白和标点帮助读者
一致的缩进、适当的空格和换行,让代码结构一目了然。代码首先是写给人看的,其次才是写给机器执行的。
气味示例三:全局变量与特殊逻辑
不要使用全局变量
全局变量让函数的行为依赖于外部状态,破坏「易于理解」和「便于修改」。应通过参数传递所需数据。
函数应返回结果,而非打印
直接 console.log 的函数无法被其他代码复用。返回结果让调用者决定如何使用。
避免特殊情形代码
到处散布的 if (x === specialCase) 会让逻辑支离一律。好的设计用统一的抽象处理所有情形。
代码长度要合适
函数不应过长(难以理解),也不应过短(过度拆分导致逻辑碎片化)。每个函数做好一件事。
重构
重构(Refactoring):改进代码的结构与可读性,而不改变代码的行为。
重构是持续改善代码品质的日常实践。在自动化测试的保护下,你可以放心地重构——测试会告诉你行为是否被意外改变。
核心要点
DRY不要重复自己;重复是 bug 的温床。
快速失败尽早暴露错误,避免错误悄悄传播。
好名字长而自描述的名字胜过含糊的缩写。
重构不改行为,只改结构;测试是重构的安全网。