编写可读代码的艺术

最近有个前辈大哥看我写的代码之后,温柔的推荐了我一本小书《编写可读性代码的艺术》

表明层次的改进

全局观注释

当某个类或者文件使用盖住是,比如是表示系统的入口点、数据如何在系统中流动等,具有全局意义的代码,写几句精心选择的话说明该代码的意义,不宜过大的篇幅。

总结性的注释

对函数做的事情进行总结,让读者在深入了解细节之前就能明白该函数的主旨。

写注释拆分成几件事:

  1. 不管你心里想什么,先把它写下来。
  2. 读一下注释,看看有没有什么地方可以改进的。
  3. 不断改进。

注释目的:

  1. 记录想法
    1. 为什么这样写(指导性)批注。
    2. 代码中的缺陷,使用像TODO或者XXX等这样的标记。

站在读者的立场上思考

  1. 预料哪些代码是读者会有疑问的,加上注释。
  2. 为普通读者意料之外的行为加上注释
  3. 用注释来总结代码块,使读者不至于迷失在细节中

怎样写出言简意赅的注释?

  1. 注释保持紧凑。不超过三行

  2. 避免使用不明确的代词,比如这、那。用有意义的名词代替,比如data、userList…

  3. 精确的描述函数的行为,比如“返回有效字符的个数”,哪些使有效字符哪些使无效字符?

  4. 某些涉及到比较复杂或者不太好用文字描述的函数,用输入输出的例子进行说明。比如“格式化字符串为下拉框格式”
    Example: listToOptionTags([{id:1,name:'a'},...]) returns [{$$typeof: Symbol(react.element), type: ƒ Option(), key: "daa7f2d8-bfd9-11e9-8...},...]

  5. 声明代码的意图,别描述字面上的意思。比如在一段for循环上写“遍历用户对象集合”,改成“以逗号分隔拼接所有用户的firstName属性”

  6. 具名函数参数,对难以理解的参数可以按照参数名对参数赋值,比如java中可以用嵌入注释的方式:

    connect(10,false); 改成 connect(/*timeout_ms=*/30,/*use_encryption=*/false)

什么地方不需要注释?

  1. 能从代码本身中迅速地推断的事实。
  2. 用来说明烂代码(比如函数名取得不明所以…),这时考虑的应该是吧代码改好。

简化循环和逻辑

把控制流变得易读

  1. 条件判断,比较的左侧通常是经常变化的值,右侧通常为不变化的值,比如:

    if(length>10)和if(10<=length),很明显前者更易读

  2. if/else的顺序,因为if/else的顺序可以自由变换,很多时候应该要考虑哪一种顺序更好,可以有以下准则:

    1. 通常情况下先处理正逻辑而不是负逻辑,比如if(haveUser)而不是if(!haveUser)
    2. 先处理简单的情况,这样的好处是可视范围内应该都能看到if/else
    3. 先处理有趣的或者更危险的情况,比如负逻辑 if not file…

所以有些规则是根据具体的情况而定的,需要我们自行判断该用哪一种形式,总之我们的目的是为了避免if/else顺序变得很别扭的情况。

  1. 三目运算符

    该表达式的可读性是存在争议的,三目表达式是一行书写,当比较内容比较简单时,使用三目会让代码看上去很紧凑和易读,不过当比较的内容比较长或者比较复杂的时候,所有代码挤在一行,这样就变得冗长了。

关键思想:相较于追求最小化代码行数,一个更好的度量方法是最小化人们理解它的时间。所以可以遵循以下原则:默认情况下都用if/else,三目表达式只有在最简单的情况下使用。

用自然语言描述代码

用自然语言描述程序,然后用这个描述写出更自然的代码。

比较适用于稍微复杂一些的场景,通过这种方式,能根据描述用的词语和过程,进而拆分出一些子问题,从而简化代码,使代码看起来更自然。

本文引用的内容,如有侵权请联系我删除,给您带来的不便我很抱歉。