likes
comments
collection
share

《重构-改善既有代码的设计》读后感

作者站长头像
站长
· 阅读数 4

关于本书

《重构-改善既有代码的设计》读后感

这本书挺厚,内容很多,示例很详细,当然价格也不便宜。我没有很详细的看,大概翻看了一遍,重点内容应该是都涵盖了。

下面随便记录一下我个人的读后感,并不是本书知识点的流水账。

读完这本书最大的感觉就是:代码绝不仅仅是用来实现功能,而是用来表达出你的设计思路和逻辑,它应该是简单的、合理的(是不是优美,这个太过于主管,看个人喜好),而不是凌乱的机器语言。hacker 也可以是艺术家。

PS:本书内容都是用 js 写的,很适合前端程序员阅读。

什么是重构

重构,这个词我们聊起来,大部分人想到的应该是:代码重写,大版本升级,换框架换语言……这些当然算重构。

但是我们忽略了一点:一些细枝末节的小改动,小调整,也算是重构。本书的主旨也是这个 —— 改善既有代码的设计 ,而不是让你重写代码。这种重构的成本是比较小的,而且可以随时进行调整。

例如:

  • 改一个变量名,让它更加语义化
  • 函数体太长了,拆分成一个一个的小函数
  • 调换一下代码的前后顺序,让相同逻辑的代码靠近一些,逻辑块之前加一个空行
  • if 里的逻辑表达式太长,提取到一个临时变量中
  • 临时变量太多,看能否用 getter 代替一些?
  • 一段逻辑太复杂,能否抽象一个 class 来封装一下?
  • ……(书中还有太多太多)……

本书讲的都是这些细枝末节,看似比起眼的例子,和我们的日常开发息息相关,有开发经验的人看到肯定会感同身受。

本书不讲什么大道理,不将设计模式,不讲框架和原理,很适合一线开发人员,以及代码 review 人员来阅读学习。

为何要重构

根本原因有两点:第一,软件最初设计时没有考虑到全部功能和细节(大型软件不能考虑那么全);第二,软件需求一直在变化。

书中还教条式的讲了很多个理由,例如:结构更加合理、编译速度更加快、查找 bug 更加简单、开发效率更高等……

但我觉得这些都不重要,我觉得让我们的设计、代码更加合理、更加易读、更加易扩展等,这些是不需要理由的,这是一名专业程序员的基本职业道德修养。 如果你作为一名程序员,只关心功能实现,而不管代码可读性、设计合理性、可扩展性等,那你并不是一名专业合格的程序员。至少目前还不是。

所以,要对你的产品代码负责,也是对你自己的职业生涯负责。 不要让你的产品出现“破窗效应”,也就是不让自己破罐子破摔。

如何更好的执行重构

完善可靠的测试集(如单元测试)

挡住重构的第一道门可能是:万一我犯错了怎么办?然后知难而退,就此拉倒了。

因此,一个可靠的测试集,就是解决这个问题的最大保障。我们前端程序员最常见的就是单元测试,工具有 jest mocha 等。 本书重点强调了测试集的作用,但是没有详细谈。推荐大家去阅读《单元测试的艺术》。

当然,你重构代码时,也需要同步修改测试集。这么好的工具,不要让它成为形式主义。

何时重构

书中作者主张,我们可以随时重构,随着日常功能开发、fix bug 而顺手重构。甚至这些都不用跟 leader 说,因为有些 leader 不懂技术,程序员又大多嘴笨,容易解释不清楚。作者认为,技术人员就要最代码负责,leader 不用管这些。

这个想法很酷,我也表示赞同。

但请大家不要套用照搬,还是要看清楚自己公司的情况。毕竟目前各个公司都要产出、要效率、要 996 。所以还是要综合考虑成本、时间、业务需求、上下游的沟通和流程,以及任务的紧急程度。 请记住,技术永远都是为业务服务的。如果业务就是要求必须要今晚上线,而你却因为要重构、写单元测试拖到明天,对于公司来说这就是不对的。

不用过于担心性能

重构,有时候会减少代码量,有时候也会增加代码量。

如下的重构示例,为了逻辑清晰,把一个 for 循环拆分为两个,但不用担心性能问题。只要不涉及性能瓶颈的操作(如 IO 、递归等),多几步 for 循环问题不大,不要担心。

// 重构前:
for (...) {
    // 逻辑1
    // 逻辑2
}

// 重构后:
for (...) {
    // 逻辑1
}
for (...) {
    // 逻辑2
}

还有,一些冗长的函数,拆分为许多个小函数,也不用担心性能问题。 反而,短小函数常常能让编译器的优化功能运转更良好,因为短小函数可以更容易被缓存。

注意分支和循环

switch 和 if else 分支应该考虑,被面向对象的多态来代替。分支是代码冗长的开始,有了分支,代码就会越写越多。

数组的 for 循环应该被 some every filter map include find 等 API 来代替。 既然语言都提供了这些 API ,就不要再自己造轮子。善用这些 API 会让代码简洁、易读、性能最优。

注意“可变数据”

可变数据,是滋生 bug 的土壤。特别是多方使用,如果一方不小心或者刻意改了,另一方不知道,就很容易产生 bug ,而且不好排查。

所以,尽量使用不可变数据。例如数据可以被封装起来,get 时返回一个副本。要修改数据,就使用特定的 API(如 delete add 等)。

另外,也尽量避免副作用。书中提到一条规则:任何有返回值的函数,都不应该有副作用。即,查询和修改要分离,不能既有查询又有修改。

多用组合,慎用继承

继承关系是非常死板固定的,还要唯一、排他性,所以必须确定是严格的父子关系,再无其他关系的可能,才用继承。而且继承和多态是相关联的,如果体现不出派生和多态,也不要用继承。

而组合关系,就比较灵活,可以随时使用组合,也可以随时增加、拆分组合。

其他

还有一些印象比较深的:

  • 纯数据,无特殊逻辑操作的,用 Map Set 等,不要用 class
  • 代码中合理使用断言 assert (断言也有注视的作用)
  • 函数不应该直接访问作用域以外的变量,慎用“自由变量”,最好用参数传递进来。

总结

我猜肯定会有人评论(或者自己想)“我们公司的代码就是一堆 xx ,根本没法重构……” 等其他的一些客观原因。 如果真如你所说所想,那你现在应该做的就是立马换工作,而且要避免再找到类似的公司。

但我想说,应该还是多从自己身上找找原因。虽然公司的代码已经这样了,通过自己的分析,能否让它变的稍微好一点点。 别管结果如何,先试着分析一下,试着改一改,试着补充一些测试。

或者,先来看看这本书。

转载自:https://juejin.cn/post/6924825677271138312
评论
请登录