The Art of Readable Code
编写可读代码的艺术
标签(空格分隔): 读书笔记
让代码更加易于理解
所有的事情都是为了让代码更加容易阅读, 衡量的标准为: 相比于代码行数, 更加倾向于其他人阅读这段代码所花费的时间
:
把信息塞进名字中
使用专业的单词
例如,不用Get, 而用Fetch或Download, 这要由上下文决定
避免空泛的名字
像tmp和retval, 除非使用它们有特殊的理由
使用具体的名字来更细致的描述事物
ServerCanStart()这个名字就比CanListenPort更不清楚
给变量名带上重要的细节
例如, 在值为毫秒的变量后面加上_ms
, 或者在还需要转义的, 未处理的变量前面加上raw_
为作用域更大的变量采用更长的名字
出现的范围越大, 范围越广, 变量的名字含义应该越丰富
有目的地使用大小写, 下划线等
例如, 你可以在类成员和局部变量前面加上"_"
来区分它们
不会误解的名字
阅读你代码的人应该理解你的本意
不要使用两义性的单词
定义一个值的下限和上限时, 使用max
和min
, 对于包含的范围, first
和last
是好的选择, 对于包含/排除范围, begin
和end
是最好的选择
在为bool值命名时,
使用is和has这样的词来明确表示它是个boolean, 避免使用反义的词
小心用户对特定词的期望
例如: 用户会期望get()
或者size()
是轻量的方法
代码的审美
如果多个代码块做相似的事情, 尝试让它们有同样的剪影
在必要时, 可以用列对齐
如果在一段代码中提到A.B和C, 那么不要再另一段话里说B.C和A, 选定一个有意义的顺序, 不要改变它
用空行来把大块代码分成逻辑上的"段落"
该写什么样的注释
什么不需要注释
- 能从代码本身中迅速推断的事实
- 用来粉饰烂代码的"拐杖式注释"–应该把代码改好
你应该记录下来的想法包括
- 对于代码写成这样而不是那样的内在理由
- 代码中的缺陷, 使用像
TODO:
或者XXX:
这样的标记 - 常量背后的故事, 为什么是这个值
站在读者的立场上思考
- 预料到代码中哪些部分会让读者说: “啊?” , 并且给它们加上注释
- 为普通读者意料之外的行为加上注释
- 在文件/类的级别上使用"全局观"注释来解释所有的部分是如何一起工作的
- 用注释来总结代码块, 使读者不致迷失在细节中
写出言简意赅的注释
- 当像it 和this 这样的代词可能指代多个事物时, 避免使用它们
- 尽量精确地描述函数的行为
- 在注释中用精心挑选的输入/输入例子进行说明(单元测试)
- 声明代码的高层次意图, 而非明显的细节
- 用嵌入的注释(如
Function(/* arg = */...)
)来解释难以理解的函数参数, 在C#里, 可以使用命名实参 - 用含义丰富的词来使注释简洁
简化循环和逻辑
把控制流变得易读
相对于追求最小化代码行数, 一个更好的度量方法是最小化人们理解它所需的时间
有几种方法可以让代码的控制流更易读
- 在写一个比较时(
while( bytes_expected > bytes_received)
), 把改变的值写在左边, 把更稳定的值写在右边更好一些(while( bytes_received < bytes_expected )
) - 重排if/else 语句中的代码块, 先处理正确的/简单的/有趣的情况
- 尽量不要使用do/while循环, 仅在必要时使用三目运算符(
:?
)和goto
- 把嵌套的代码块改写成线性的代码
- 通常来讲可以使用提前返回来减少嵌套, 此种语句被称为"保护语句"
拆分超长的表达式
- 引用"解释变量"来代表较长的子表达式
- 他把巨大的表达式拆成小段
- 它通过用简单的名字描述子表达式来使代码文档化
- 帮助读者识别代码中的主要概念
- 使用德摩根定理来操作逻辑表达式, 重写布尔表达式
变量与可读性
- 减少变量
- 减小每个变量的作用域
- 只写一次的变量更好
重新组织代码
抽取不相关的子问题
把公共代码和项目专有的代码分开, 例如使用Common.dll
一次只做一件事
把想法变成代码
使用自然语言描述程序, 然后用这个描述来帮助你写出更自然的代码
少写代码
- 从项目中消除不必要的功能, 不要过度设计
- 重新考虑需求, 解决版本最简单的问题, 只要能完成工作就行
- 经常性通读标准库的整个API, 保持对它们的熟悉程度
附加
测试与可读性
- 每个测试的最高一层应该越简明越好. 最好每个测试的输入/输出都可以用一行代码来描述
- 如果测试失败了, 它所发出的错误消息应该能让你容易跟踪并修正这个bug
- 使用最简单的并且能够完整运用代码的测试输入
- 给测试函数取一个有完整描述性的名字, 以使每个测试所测的东西都很明确.
- 使测试易于改动和增加新的测试