📖 编写可读代码的艺术

《代码整洁之道》讲解得深入一些,此书则属于简单易懂。

  1. 在《Clean Code》一书中Bob大叔认为在代码阅读过程中人们说脏话的频率是衡量代码质量的唯一标准。
  2. 尽管减少代码行数是一个好的目标,但把理解代码所需的时间最小化是一个更好的目标。
  3. 为名字附带更多信息,比如单位或者属性(size_mb, html_utf8

把信息装到名字里

  • 使用专业的单词——例如,不用Get,而用Fetch或者Download可能会更好。
  • 避免空泛的名字,像tmp和retval,除非使用它们有特殊的理由。
  • 使用具体的名字来更细致地描述事物——ServerCanStart()这个名字比CanListenOnPort更不清楚。
  • 给变量名带上重要的细节——例如,在值为毫秒的变量后面加上_ms,或者在还需要转义的,未处理的变量前面加上raw_
  • 为作用于大的名字采用更长的名字——不要用让人费解的一个或两个字母的名字来命名在几屏之间都可见的变量。对于只存在于几行之间的变量用短一点的名字更好。
  • 有目的的使用大小写、下划线等——例如,你可以在类成员和局部变量后面加上”_“来区分它们。(类成员变量末尾添加下划线)

不会误解的名字

  • 蒂=定义一个值的上限或下限时,max_min_是很好的前缀。
  • 对于包含的范围,firstlast是最好的选择。(1-first,2,3-last)
  • 对于包含/排除范围,beginend是最好的选择。(1-begin,2,3,-end)
  • 为布尔值命名时,使用ishas这样的词来明确表示它是个布尔值,避免使用反义的词(例如disable_ssl)。

审美

  • 如果多个代码块做相似的事情,尝试让他们有同样的剪影。
  • 把代码按“列”对齐可以让代码更容易浏览。
  • 如果在一段代码中提到A、B和C,那么就不要在另一段中说B、C和A。选择一个有意义的顺序,并始终用这样的顺序。
  • 用空行来把大块代码分成逻辑上的“段落”。

该写什么样的注释

  • 什么地方不需要注释:
    1. 能从代码本身中迅速推断的事实。
    2. 用来粉饰烂代码的“拐杖式注释”——应该把代码改好。
  • 应该记录下来的想法:
    1. 对于为什么代码是这样而不是那样的内在理由。
    2. 代码中的缺陷,使用像TODO:或者XXX:这样的标记。
    3. 常量背后的故事,为什么是这个值。
  • 站在读者的立场思考:
    1. 预料代码中哪些部分会让读者说:“啊?”并且给它们加上注释。
    2. 为普通读者意料外的行为加注释。
    3. 在文件/类的级别上使用“全局观”注释来解释所有部分如何一起工作的。
    4. 用注释来总结代码块,使读者不至于秘史在细节中。

写出言简意赅的注释

  • 当像“it”和“this”这样的代词可能指代多个事物时,避免使用它们。
  • 尽量精确的描述函数的行为。
  • 在注释中用精心挑选的输入/输出例子进行说明。
  • 声明代码的高层次意图,而非明显的细节。
  • 用嵌入的注释(如Function(/*arg =*/...))来解释难以理解的函数参数。
  • 用含义丰富的词来使注释简洁。

把控制流变得易读

  • 在写一个比较时(while (bytes_excepted > bytes_received)),把改变的值写在左边,并且把更稳定的值写在右边更好一些 (while (bytes_received < bytes_expected))。
  • 可以重新排列 if/else 语句中的语句块。通常来讲,先处理正确的/简单的/有趣的情况。
  • 某些编程结构,像三目运算符 (:?)、do/while 循环,以及 goto 经常会导致代码的可读性变差。最好不要使用它们,因为总是有更整洁的代替方式。
  • 嵌套的代码块需要更加集中精力理解。每层新的嵌套都需要读者把更多的上下文“压入栈”。应该改把它们改写成更加“线性”的代码来避免深嵌套。
  • 通常来讲,提早返回(return)可以减少嵌套并让代码整洁。“保护语句”(在函数顶部处理简单的情况时)尤其有用。

拆分超长的表达式

  • 解释变量用来代表较长的子表达式。
  • 解释变量把巨大的表达式拆成小段。
  • 解释变量用简单的名字描述子表达式来让代码文档化。
  • 解释变量让读者识别代码中的主要概念。

变量与可读性

  • 减少变量,即那些妨碍的变量。
  • 减少每个变量的作用域,越小越好。把变量移到一个有最少代码可以见到它的地方。眼不见,心不烦。
  • 只写一次的变量更好。那些只设置一次值的变量(或者const、final、常量)使得代码更容易理解。

抽取不相关的子问题

  • 把一般代码和项目专有的代码分开

关键思想

  • 代码应当易于理解。
  • 代码的写法应当使别人理解它所需的时间最小化。
  • 把信息装入名字中。
  • 要多问自己几遍:“这个名字会被别人解读成其他的含义吗?”要仔细审视这个名字。
  • 一致的风格比“正确”的风格更重要。
  • 注释的目的是尽量使读者了解得和作者一样多。
  • 不要为那些从代码本身就能快速推断的事实写注释。
  • 注释应当有很高的信息/空间率。
  • 把条件、循环以及其他对控制流的改变做得越“自然”也好,运用一种方式使读者不用停下来重读你的代码。
  • 把超长的表达式拆分成更容易理解的小块。
  • 让你的变量对尽量少的代码行可见。
  • 操作一个变量的地方越多,越难确定它的当前值。
  • 应该把代码组织得一次只做一件事。

技巧 标记

  • TODO:待处理的事情
  • FIXME:已知无法运行的代码
  • HACK:对一个问题不得不采用比较粗糙的解决方案
  • XXX:危险!这里有重要的问题。