《编写可读代码的艺术》读书笔记

前言

1. 代码应当易于理解

把理解代码所需的时间最小化

第一部分 表面层次的改进

2. 把信息装到名字里

1)使用专业的单词,如将get换位fetch、download等;

2)避免空泛的名字,如tmp,retval,除非使用他们有特殊的理由;

3)用具体的名字代替抽象的名字

4)给变量名带上重要的细节,如未处理的变量前面加raw_,值为毫秒的变量后面加_ms;

5)为作用域大的名字采用更长的名字,不要用让人费解的一两个字母来描述满屏可见的变量,对于只存在与几行之间的变量可用短一点的名字;

6)有目的的使用大小写,下划线等,如在类成员和局部变量后面加“_”区分。

wordalternatives
stopkill, pause(反: resume)
senddeliver, dispatch, announce, distribute, route
startlaunch, create, begin, open
makecreate, set up, build, generate, compose, add, new

3. 不会误解的名字

1)不会误解的名字是最好的名字

2)当要定义一个值的上下限时,可以用max_、min_这样的前缀;对于包含的范围,first和last是好的选择;对于包含/排除范围,begin和end是最好的选择

3)当为布尔值命名时,使用is或has这样的词来明确表示它是个布尔值,避免使用反义的词

4)小心对特定词的期望,如f.size() 和 f.countSize()、getMean() 和 computeMean()等。

4. 审美

1)使用一致的布局,让读者很快习惯这种风格;

2)让相似的代码看上去相似;

3)把相关的代码行分组,形成代码块。

5. 该写什么样的注释

 关键思想:注释的目的是尽量帮助读者了解的和作者一样多;

                   不要为那些从代码本身就能快速推断的事实写注释;

什么地方不需要注释:

        1)能从代码本身中迅速推断的事实;

        2)用来粉饰烂代码的“拐杖式注释”,应该把代码改好。

应该记录下来的想法包括:

        1)对于为什么代码写成这样而不是那样的内在理由(“指导性批注”);

        2)代码中的缺陷,使用像TODO、XXX这样的标记;

        3)常量背后的故事,为什么是这个值。

站在读者的立场上思考:

        1)预料到代码中哪些部分会让读者产生“?”,并给他们加上注释;

        2)为普通读者预料之外的行为加上注释;

        3)在文件/类的级别上使用“全局观”注释来解释所有部分是如何一起工作的;

        4)用注释来总结代码块,使读者不至迷失于细节之中。

6. 写出言简意赅的注释

关键思想:注释应当有很高的信息/空间率,把更多的信息装入到更小的空间里

1)当像 “it” 和 “this” 这样的代词可能指代多个事物时,避免使用他们;

2)尽量精确地描述函数的行为;

3)在注释中用精心挑选的输入、输出例子进行说明;

4)声明代码的高层次意图,而非明显的细节;

5)用嵌入的注释(如function(/*arg = */...))来解释难以理解的函数参数;

6)用含义丰富的词来使注释简洁。

第二部分 简化循环和逻辑

        第一部分介绍了表面层次的改进,那是一些改进代码可读性的简单方法,一次一行,在没有很大的风险或者花很大代价的情况下就可以应用。

        第二部分将进一步深入讨论程序的 “循环和逻辑” :控制流、逻辑表达式以及让你的代码正常运行的那些变量。

7. 把控制流变得易读

关键思想:

        把条件、循环以及其他对控制流的改变做得越 “自然” 越好,运用一种方式使读者不用停下来重读你的代码;

        相对于追求最小化代码行数,更好的度量方法是最小化人们理解它所需的时间;

        当你对代码做改动时,从全新的角度审视它,把它作为一个整体来看待;

编程结构高层次程序流程是如何变得不清晰的
线程不清楚什么时间执行什么代码
信号量/中断处理程序有些代码随时都有可能执行
异常可能会从多个函数调用中向上冒泡一样地执行
函数指针和匿名函数很难知道到底会执行什么代码,因为在编译时还没有决定
虚方法object.virtualMethod()可能会调用一个未知子类的代码

1)在写比较时,把改变的值写在左边并且把更稳定的值写在右边更好一些,如 " x>=n";

2)在排列if/else语句时,通常先处理正确的、简单的、有趣的情况;

3)某些编程结构,如三目运算符、do/while结构、goto等会导致代码的可读性变差,尽量不要使用他们;

4)嵌套的代码块需要更加集中精力去理解,每层新的嵌套都需要读者把更多的上下文“压栈”;

5)通常来讲,提早返回可以减少嵌套并让代码整洁。

8. 拆分超长的表达式

 关键思想:

        把超长表达式拆分成更容易理解的小块

        要小心“智能”的小代码段,它们往往在以后会让别人读起来干到困惑

1)引入 “解释变量” 来代表较长的子表达式;

2)用德摩根定理来操作逻辑表达式,如  if(!(a && b)) 变成 if(!a || b)。

9. 变量与可读性

 三个问题:

        1)变量越多,就越难全部跟踪它们的动向;

        2)变量的作用域越大,就需要跟踪它的动向越久;

        3)变量改变得越频繁,就越难以跟踪它的当前值。

关键思想:

        让你的变量对尽量少的代码可见

        操作一个变量的地方越多,就越难确定它的当前值

1)减少变量,即那些妨碍的变量,通过立刻处理结果消除 “中间结果” 变量;

2)减小每个变量的作用域,越小越好,把变量移到一个有最少代码可以看到的地方;

3)只写一次的变量更好,通过const、final 使得代码更容易理解。

第三部分 重新组织代码

        第二部分讨论了如何改变程序的“循环与逻辑”来让代码更有可读性。

        第三部分会讨论可以在函数级别对代码做出更大的改动。具体来讲,会讲到三种组织代码的方法:

  • 抽取出那些与程序主要目的 “不相关的子问题”;
  • 重新组织代码使它一次只做一件事;
  • 先用自然语言描述代码,然后用这个描述来帮助你找到更整洁的解决方案。     

10. 抽取不相关的子问题

积极地发现并抽取出不相关的子逻辑

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

11. 一次只做一件事

 关键思想:应该把代码组织得一次只做一件事

12. 把想法变成代码

 用自然语言描述程序然后用这个描述来帮助写出更自然的代码

13. 少写代码

 关键思想:最好读的代码就是没有代码

避免编写新代码:

        1)从项目中消除不必要的功能,不要过度设计;

        2)重新考虑需求,解决版本最简单的问题,只要能完成工作就行;

        3)经常性地通读标准库的整个API,保持对他们的熟悉度。

第四部分 精选话题

14. 测试与可读性

关键思想:

        测试应当具有可读性,以便其他程序员可以舒服地改变或者增加测试

        应当选择一组最简单的输入,它能完整地使用被测代码

        又简单又能完成工作的测试值更好

测试原则:对使用者隐去不重要的细节,以便更重要的小细节会更突出

测试驱动开发

如何改进测试的几个具体要点:

1)每个测试的最高一层应该越简明越好,最好每个测试的输入、输出可以用一行代码来描述;

2)如果测试失败了,它所发出的错误消息应该能让你容易跟踪并修正bug

3)使用最简单的并且能够完整运用代码的测试输入

4)给测试函数取一个有完整描述性的名字,使每个测试所测到的东西很明确,如test_<function>_<situation>;

5)要使他易于改动和增加新的测试。

15. 设计并改进“分钟/小时计数器”

附录 深入阅读

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值