代码应当易于理解
可读性基本原理
关键思想: 代码的写法应当使别人理解它所需的时间最小化。
可读性基本定理总是先于任何其他条例或原则。
表面层次的改进
如果你的代码有很棒的名字、写的很好的注释,并且整洁地使用了空白符,你的代码会变得易读很多。
命名艺术
- 选择专业的词
- 选择的词要能表达清楚信息,比如树的高度,就可以用 height 而不是 size。
- 避免泛泛的名字(或者说要知道什么时候使用它)
- 好的名字应当描述变量的目的或者它所承载的值。
- 比如 tmp,如果这个变量的唯一目的就是临时存储,它的整个生命周期只在几行代码之间,这个变量没有其他职责,不会被传到其他函数中国或者被重置以反复使用,那么就可以使用 tmp, 但是如果变量最重要的目的不是临时存储,那么就应该用一个可以表示变量意义的名字来代替 tmp ,这样会更加具有描述性。
- 用具体的名字代替抽象的名字
- 使用前缀或后缀来给名字附带更多信息
- 比如变量如果表示时间,可以加上单位来让变量表示更加清晰。
- 决定名字的长度
- 如果变量作用域比较小,可以不用附带太多信息,名字长度可以短一些。
- 如果名字中的某些单词可以拿掉而不会损失任何信息,那么久可以丢掉这些没用的词。
- 如果变量作用域比较大,可以采用比较长的名字,易于理解。
- 利用名字的格式来表达含义
- 有目的地使用大小写。
- 不会误解的名字
- 很多英语单词在用来编程时是具有多义性的,在命名的时候,需要考虑这个名字是否会被误解为另外一种意思,好的名字是不会被误解的。
审美艺术
养眼代码的原则
- 选择一个有意义的顺序,并且始终一致地使用它。
- 让相似的代码看上去相似。比如可以采用列对齐的方式来排列参数,让代码看上去更清晰易读。但是这样也存在维护困难的问题,所以要慎重考虑。
- 把相关的代码行分组,形成代码块。比如输入、实现、输出就可以分成不同的代码块。
关键思想:一致的风格比“正确”的风格更加重要。
注释艺术
关键思想:
- 注释的目的是尽量帮助读者了解得和作者一样多。
- 不要为那些从代码本身就能快速推断的事实写注释。
什么时候加注释
- 可以为代码中的瑕疵加注释,比如TODO、FIXME等。
- 可以用注释来总结代码块,易于读者理解。
加注释的要点
关键思想:注释应当有很高的信息/空间率。
- 避免使用不明确的代词,比如 it。
- 精确描述函数的行为。
- 声明代码的高层次意图,而非明显的细节。
- 用含义丰富的词来使注释更加简洁。
控制流艺术
关键思想:把条件、循环以及其他对控制流的改变做的越“自然“越好,运用一种方式使读者不用停下来重读你的代码。
原则:
- 在写一个比较时,比较的左侧表达式的值更倾向于不断变化,比较的右侧表达式的值更倾向于常量。
比如:while(bytes_received < bytes_expected)
比while(bytes_expected > bytes_received)
更易读懂。 - 在写
if/else
语句的语句块时,if 中国尽量先处理正确的、简单的情况。比如,用if(debug)
而不是if(!debug)
- 尽量使用线性的代码,避免深层次的嵌套。
表达式艺术
关键思想:把超长的表达式拆分成更容易理解的小块。
方法:
- 引入解释变量来代表子表达式,帮助读者理解长表达式的意思。
- 用德摩根定理来操作逻辑表达式,比如,
if(!(a && b))
可以变为if(!a || b)
。
变量艺术
原则
- 减少变量,比如一个临时变量只用过一次,就没有必要声明这个变量,因为它没有压缩任何冗余代码。
- 缩小变量的作用域,变量的作用域越大,越难掌握在哪里会用到这些变量,有可能会出现局部变量改变全局变量的情况。
- 那些只设置一次值得变量,比如const、final等,可以 让代码更容易理解。
一次只做一件事的艺术
关键思想:应该把代码组织得一次只做一件事情。
流程:
- 列出代码所做的所有任务。
- 尽量把这些任务拆分到不同的函数中。或者至少是代码中的不同的段落中。
把想法变成代码
流程:
- 假设你面前有一个人,对着他清楚地描述代码要做什么,它的逻辑是什么。
- 注意描述中所用的关键词和短语。
- 写出与描述所匹配的代码。
Tips:如果需要,可以买一只小黄鸭,让它听你描述。
少写代码的艺术
关键思想:最好读的代码就是没有代码。
避免写新代码的原则:
- 从项目中消除不必要的功能,不要过度设计。
- 重新考虑需求,解决版本最简单的问题,只要能完成工作就行。
- 多读标准库中的API,保持对它们的熟悉程度。
测试与可读性
关键思想:测试应当具有可读性,以便于其他程序员可以舒服地改变或者增加测试。
改进测试的要点:
- 测试的输入/输出最好可以用一行代码来描述。
- 测试失败后发出的错误信息要易于让你去跟踪并修正这个bug。
- 使用最简单并且能够完整运用代码的测试输入。
- 给测试函数取一个有完整描述性的名字。