禅道博客

分享专业技术知识,文章内容干货满满

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

2023-12-21 15:18:34
潘仙芝
原创 626
摘要:编写可读代码的艺术包括表面层次的改进、简化循环和逻辑、重新组织代码等多个方面。

一、代码应当易于理解

代码的写法应当使别人理解它所需的时间最小化

二、表面层次的改进

1. 把信息装入名字里

· 选择专业的词

· 清晰精确比装可爱好

· get  fetch download

· 找到更有表现力的词

· 避免泛泛的名字(或者说要知道什么时候使用它)

· 比如tmpretval

· 用具体的名字代替抽象的名字

· 为名字附带更多信息

· 带单位的值,带单位的参数

· 附带其他重要属性

· 使用前缀或后缀来给名字附带更多信息

· 决定名字的长度

· 隐含的约束,名字不能太长

· 在小的作用域中使用短的名字

· 利用名字的格式来表达含义

· 首字母缩略词和缩写

· 丢掉没用的词

· 总结

· 把信息塞入名字里

· 使用专业的单词

· 使用空泛的名字

· 使用具体的名字来更细致地描述事物

· 给变量名带上重要的细节

· 为作用域大的名字采用更长的名字

                                           · 有目的的使用大小写、下划线等

2.不会误解的名字


· 多问几遍:这个名字会被别人解读成其他的含义吗?

· 命名极限最清楚的方式是在要限制的东西前加上max_min_

· 推荐使用firstlast来标识包含范围

· 使用beginend来标识包含/排除范围

· 与使用者的期望相匹配

· 如何权衡多个备选名字

3.审美

· 从审美的角度讲让人愉悦的代码更容易

· 重新安排换行来保持一致和紧凑

· 用方法来整理不规则的东西

· 在需要时使用列对齐

· 列提供可见的栏杆

· 让相似的代码看起来相似

· 选一个有意义的顺序,始终一致地使用它

· 把声明按块组织起来

· 把代码分成段落

· 个人风格与一致性

· 一致的风格比正确的风格更重要

· 总结

· 代码用一致的有意义的方式格式化

· 多个代码块做相似的事情,尝试让它们有同样的剪影

· 把代码按列对齐可以让代码更易浏览

· 选择一个有意义的顺序并始终用这样的顺序

· 用空行把大块代码分成逻辑上的段落

4.改写怎样的注释


· 注释的目的是尽量帮助读者了解的和作者的一样多

· 什么不需要注释

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

· 不要为了注释而注释

· 好代码>坏代码+好注释

· 不要给不好的名字加注释,应该把名字改好

· 记录你的思想

· 加入导演评论

· 为代码中的瑕疵写注释

· 给常量加注释

· 站在读者的角度

· 意料之中的提问

· 公布可能的陷阱

· 全局观注释

· 总结性注释

· 最后的思考,克服作者心理阻滞

· 不管你心理想什么,先写下来

· 读一下这段注释,看看有什么可以改进的

· 不断改进

· 总结

· 什么地方不需要注释

· 能从代码本身迅速推断事实

· 用来粉饰烂代码的拐杖式注释,应把代码改好

· 你应该记下来的想法

· 对于为什么代码写成这样而不是那样的内在理由,指导性批注

· 代码中的缺陷,使用像TODO:或者XXX:这样的标记

· 常量背后的故事,为什么是这个值

· 站在读者的立场上思考

· 预料到代码中哪些部分会让读者说:啊?,并且加上注释

· 为普通读者预料之外的行为加上注释

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

· 用注释总结代码块,使读者不至于迷失在细节中

5.写出言简意赅的注释


· 注释应当有很高的信息/空间率

· 让注释保持紧凑

· 避免使用不明确的代词

· 润色粗糙的句子

· 精确地描述函数的行为

· 用输入/输出例子来说明特别的情况

· 声明代码的意图

· 具名函数的注释

· 采用信息含量高的词

· 总结

· 当像 it  this 这样的代词可能指代多个事物时,应避免使用它们

· 尽量精确地描述函数的行为

· 在注释中用精心挑选的输入和输出例子来说明

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

· 用嵌入的注释来解释难以理解的函数参数

· 用含义丰富的词来使注释简洁

 

三、简化循环和逻辑

1.把控制流变得易读

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

· 条件语句中的参数顺序

· if/else语句块的顺序

· ?:条件表达式,三目运算符

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

· 默认情况下使用if/else?:三目运算符只有在最简单的情况下使用

· 避免do/while循环

· 从函数中提前返回

· 臭名昭著的goto

· 最小化嵌套

· 嵌套是如何累积而成的

· 通过提早返回来减少嵌套

· 减少循环内的嵌套

· 把循环、条件和其他跳转写得简单易读

· 总结

· 写一个比较时,把改变的值写在左边并且把更稳定的值写在右边更好一些

· 重新排列if/else语句的语句块,先处理正确的简单的有趣的情况。有时这些准则会冲突,但是当不冲突时,这是要遵循的经验法则

· 三目运算符、do/while循环、goto经常会导致代码的可读性变差。最好不要用它们,总是有更整洁的代替方式

· 嵌套的代码块应改写成更加线性的代码来避免神嵌套


· 在函数顶部处理简单的情况尤其有用

2.拆分超长的表达式


· 用做解释的变量

· 总结变量

· 使用德摩定理

· 滥用短路逻辑

· 要小心 智能 的小代码段,它们往往在以后会让别人读起来感到困难

· 找更优雅的方式

· 拆分巨大的语句

· 另一个简化表达式的创意方法

· 总结

· 把巨大的表达式拆成小段

· 通过简单的名字描述子表达式来让代码文档化

· 帮助读者识别代码中的主要概念

3.变量和可读性


· 问题

· 变量越多,越难全部跟踪它们的动向

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

· 变量改变得越频繁,越难以跟踪它的当前值

· 减少变量

· 没有价值的临时变量

· 减少中间结果

· 减少控制流变量

· 缩小变量的作用域

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

· 不同语言不同的管理作用域规则

· C++if语句作用域

· JavaScript创建 私有 变量

· JavaScript全局作用域

· PythonJavaScript中没有嵌套的作用域

· 把定向向下移

· 只写一次的变量更好

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

· 总结

· 减少变量

· 减小每个变量的作用域

· 只写一次的变量更好

四、重新组织代码

1.抽取不相关的子问题


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

· 纯工具代码

· 其他多用途代码

· 意料之外的好处

· 创建大量通用代码

· 项目专有的功能

· 简化已有接口

· 按需重塑接口

· 过犹不及

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

2.一次只做一件事


· 应该把代码组织得一次只做一件事情

· 任务可以很小

· 从对象中抽取值

3.把想法变代码


· 清楚地描述逻辑

· 了解函数库是有帮助的

· 把这个方法应用于更大的问题

· 用自然语言描述解决方案

· 递归地使用这种方法

4.少写代码


· 最好读的代码就是没有代码

· 别费神实现那个功能,你不会需要它

· 质疑和拆分你的需求

· 保持小代码库

· 让你的代码库越小越轻量越好

· 删除没用的代码

· 熟悉你周边的库

· 为什么重用库有这么大的好处

· 避免编写新代码

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

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

· 经常性地通读标准库的整个API,保持对它们的熟悉程度

四、精选话题

1.测试与可读性


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

· 程序员会不敢修改真实代码

· 程序员不会再增加新的测试

· 这段测试什么地方不对

· 使整个测试更可读

· 创建最小的测试声明

· 实现定制的 微语言

· 让错误消息具有可读性

· 手工打造错误信息

· 选择好的测试输入

· 简化输入值,简单又能完成工作的测试值更好

· 一个功能的多个测试

· 为测试函数命名

· 对测试较好的开发方式

· 测试驱动开发

· 走得太远

· 牺牲真实代码的可读性,只是为使能测试

· 着迷于100%的测试覆盖率

· 让测试成为产品开发的阻碍

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


· 定义类接口

· 改进命名

· 改进注释

· 得到外部视角的观点

· 尝试1:一个幼稚的方案

· 这段代码易于理解吗?

· 一个更易读的版本

· 性能问题

· 它一直不停地在变大

· MinuteCount()HourCount()太慢了

· 尝试2:传送带设计方案

· 实现两阶段传送带设计

· 这个设计不灵活

· 这个类占用的内存很大

· 尝试3:时间桶设计方案

· 实现时间桶设

· 实现TrailingBucketCounter

· 实现ConveyorQueue

 


关键字

暂时没有记录
评论通过审核后显示。