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

概述:
编写程序,如何让程序持续可维护是一项难题。通过对代码的可读性优化,可以让程序变得相对容易维护一些。因此,我们有必要研究研究代码的可读性。《编写可读代码的艺术》这本书读起来感觉不错。花了大半天的时间通读了一遍,随手做了些笔记,当做学习的一部分。有兴趣读的朋友可以在文末免费获取该书的电子档。

以下为通读笔记:


总的来说,目标只有一个—让代码变得易于理解(可读性基本定理)基于此扩展出其他详细细节与方法,当其他方法与该原则冲突时,以遵循此原则为主。

基于可读性基本定理,并不建议代码越小越好,而是应当使别人理解它所花的时间最小化。具体做法有以下十点:
1 写好命名 – 把信息装进名字里
2 不使用歧义的名字 – 考虑该命名是否被误解
3 追求审美 – 统一代码风格
4 写好注释 – 标注好该标注的事情
5 控制流优化 – 把控制流变得易读
6 不使用超长表达式 – 拆分超长表达式
7 变量的可读性 – 尽可能少的变量、尽可能缩小作用域、尽可能减少变量赋值
8 重新封装 – 抽取不相关子问题,重构封装
9 拆分函数 – 每次只做一件事
10 少写代码 – 剔除无用功能,避免过度设计过度开发

以下为脉络笔记:


第一部分 — 表面层次的改进

第一章 — 代码应当易于理解

  1. 可读性基本定理 — 代码的写法应当使别人理解它所需的时间最小化

  2. 代码不是越小越好

  3. 理解代码所需时间与其他目标有冲突时,考虑第一条原则

  4. 选择好的名字

  5. 写好的注释

  6. 把代码整洁的写成更好的格式

第二章 — 把信息装到名字里
无论是命名变量、函数还是类,都可以使用很多相同的原则,把名字当做一条小小的注释
关键思想 — 把信息装入名字中

  1. 选择专业的词
  2. 避免泛泛的名字(要知道什么时候使用它)【给名字带上属性】
  3. 用具体的名字代替抽象的名字
  4. 使用前缀或后缀给名字附带更多信息(更具体的变量,如带单位等)
  5. 决定名字的长度
  6. 首字母缩略词和缩写经验原则
  7. 丢掉没用的词
  8. 利用名字的格式来表达含义

名字的长度:

  1. 在小的作用域里可以使用短的名字
  2. 在大的作用域里名字就要包含足够的信息以便含义更明确

首字母缩略词和缩写经验原则:团队的新成员是否能理解这个名字的含义,如果能,那就可能没有问题。

丢掉没用的词

名字的格式(以C++为例)

CamelCase — 类名
lower_separated — 变量名
kConstantName — 常量
MACRO_NAME — 宏
offerset_ — 类成员变量

第三章 — 不会误解的名字(关键思想—多问自己几遍,“这个名字会被别人误解成其他含义吗”)

  1. 推荐用min和max来表示(包含)极限
  2. 推荐用first和last来包含范围
  3. 推荐用begin和end来包含/排除范围
  4. 给布尔值命名(避免使用反义词命名)
  5. 阅读你代码的人应理解你的本意,而且不会有其他的理解。在决定使用一个名字以前,吹毛求疵一点,想象一下名字会被误解成什么,最好的名字是不会被误解的。

第四章 — 审美

三条原则

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

  2. 让相似的代码看上去相似

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

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

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

  6. 在需要时使用列对齐

  7. 选一个有意义的顺序,始终一致的使用

  8. 从最重要到最不重要

  9. 按字母顺序排序(如果在一段代码中提到ABC,那么不要在另外一段代码中变成BCA,选择有意义的顺序,并始终使用)

  10. 把声明按块组织起来

  11. 把代码分成“段落”

  12. 个人风格与一致性。(个人的风格要与团队的风格保持一直,若冲突则舍弃)

第五章 — 注释

  1. 了解什么不需要注释(不要为那些从代码本身就能快速推断的事实写注释,不要为了注释而注释)
  2. 用代码记录你的思想
  3. 站在读者的角度,去想想他们需要知道什么
  4. 不要给不好的名字加注释—应该把名字改好
  5. 记录你的思想
  6. 加入“导演评论”
  7. 给常量加注释
  8. 站在读者角度(意料之中的提问,当别人读你的代码时,有部分可能让他们有种为什么的想法,你的工作就是要给这些部分加上注释)
  9. 公布可能的陷阱(这段代码有什么出人意料的地方,会不会被误用)
  10. 全局观注释
  11. 总结性注释
  12. 克服“作者心里阻滞”(不想写注释),【因此,当你对注释犹豫不决时,直接把心里想的写下来就好了,然后读一下看看有什么可以改进的,最后不断改进】

注释的标记:
TODO:我还没处理的事情(可以用todo:(小写)表示次要缺陷)
FIXME:已知无法运行的代码
HACK:对一个问题不得不采用的比较粗糙的解决方案
XXX:危险!这里有重要问题

第六章 — 写出言简意赅的注释

  1. 让注释保持紧凑
  2. 避免使用不明确的代词
  3. 润色粗糙的句子
  4. 精确的表述函数的行为
  5. 对输入/输出例子来说明特别的情况
  6. 声明代码的意图
  7. “具名函数参数”的注释(不加注释的参数有些看不懂)【如connect(10,false); 10和false的含义使函数调用有点难以理解】
  8. 采用信息含量高的词

第二部分 — 简化循环和逻辑

第七章 — 把控制流变得易读

比较式的左边更倾向于不断变化
比较式的右边更倾向于常量

if/else语句块的顺序

  1. 先处理正逻辑
  2. 先处理简单情况
  3. 先处理有趣的或者可疑的情况

三目运算
默认情况都用if/else ,只有在最简单的情况下使用三目运算

避免do/while循环
实践当中大多数do/while都可以写成while

从函数中提前返回(有结果的可以尽可能早的return)

避免使用goto

最小化嵌套

  1. 嵌套是如何积累而成的(当你对代码改动时,把它看做一个整体重新审视对待)
  2. 通过提早return减少嵌套
  3. 减少循环内的嵌套

理解执行流程
理想的情况是整个程序的执行路径都很容易理解—从main函数开始一步步执行,直到程序结束

低层次控制流:循环、条件、跳转
高层次控制流:线程、信号量/终端处理程序、异常、函数指针和匿名函数、虚方法
(高层次程序流程如何变得不清晰的)
线程:不清楚什么时间执行代码
信号量/终端处理程序:有些代码随时都可能执行
异常:可能会从多个函数调用中像冒泡一样执行
函数指针和匿名函数:很难知道会执行什么代码,因为在编译时还没决定
虚方法:可能会调用一个未知子类的代码

第八章 — 拆分超长的表达式
【研究表明,大多数人同时只能考虑3-4件事,简单来说,代码中的表达式越长,它就越难理解】

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

  1. 用做解释的变量(拆分表达式最简单的方法就是引入一个额外的变量,让他来表示一个小一点的子表达式)
  2. 总结变量(把一个不需要解释的表达式装入一个新的变量中仍然有用,我们叫它做总结变量,目的是只用一个很短的名字来代替一大块代码,这样更容易管理和思考)
  3. 使用德摩根定理(分别取反,转换与/或)
  4. 滥用短路逻辑
  5. 找到更优雅的方式。
  6. 拆分巨大的语句
  7. 另一个简化表达式的创意方法 — 使用宏

第九章 — 变量与可读性

  1. 减少变量
  2. 没有价值的临时变量
  3. 减少中间结果
  4. 减少控制流变量
  5. 缩小变量的作用域
  6. 把定义向下移(把每个定义移动到对它使用前,而不是定义在类最上面)
  7. 只写一次的变量更好(操作一个变量地方越多,越难确定它当前值)

第三部分 — 重新组织代码

第十章 — 抽取不相关的子问题(积极发现并抽取不相关的自逻辑)
【所谓工程学,就是把大问题拆分成小问题,再把这些问题的解决方案放回一起】

  1. 看看某个函数或代码块,问问自己,这段代码高层次目标是什么
  2. 对于每一行代码,问一下,它是直接为了目标而工作吗,搞层次目标是什么
  3. 如果足够行数在解决不相关的子问题,抽取代码到独立的函数中
  4. 纯工具代码
  5. 其他多用途代码
  6. 创建大量通用代码
  7. 项目专有的功能
  8. 简化已有接口
  9. 按需重塑接口

第十一章 — 一次只做一件事

  1. 列出代码所做的所有任务
  2. 任务可以很小
  3. 从对象中抽取值
  4. 尽可能把这件任务拆分到不同的函数中,或者至少是代码不同的段落中
  5. 应用一次只做一件事原则

第十二章 — 把想法变成代码

  1. 清楚的描述逻辑
  2. 了解函数库
  3. 把方法应用于更大的问题
  4. 用自然语言描述解决方案
  5. 递归地使用这种方法

第十三章 — 少写代码

  1. 从项目中消除不必要的功能,不要过度设计
  2. 质疑和拆分需求,解决版本最简单的问题,只要能完成工作就行
  3. 保持小代码库
  4. 经常了解标准库的API,保持对它们的熟悉读

第四部分 — 精选话题

第十四章 — 测试与可读性

  1. 使得测试易于阅读和维护(测试应当具有可读性,以便其他程序员可以改变或增加测试)
  2. 每个测试的最高一层应越简明越好,最好每个测试的输入输出都可以用一行代码来描述
  3. 如果测试失败了,它所发出的错误消息应能让你容易跟踪并修正这个bug
  4. 使用最简单且完整运用代码的测试输入
  5. 给测试函数取一个有完整性描述的名字,不要用test1这种名字

第十五章 — 设计并改进“分钟/小时计数器”

研究iOS的朋友可以入群一起讨论,Q群号:201708926

电子书《编写可读代码的艺术》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值