dahua-dijkstra

读经典【1】重构:改善既有代码的设计

书评

五星好评。很实用。

最近读了重构原版书,同时也在使用其中的一些技巧来改善工作中的项目,自己改完代码会有成就感。

这本书改变了我原有的思想钢印:代码能成功跑起来就不要去动它。实际上,通过好的代码是通过不断重构和迭代实现的。

转念一想,我们喷别人写的代码是屎山,实际上自己的代码也不咋地,代码很重要的可读性就是问题,我们往往在自己写的时候不去考虑可读性,只靠问题的实现,这时我们头上戴着“实现”的帽子,实现了既有目标+自测后,代码就束之高阁了。当更多的历史代码无法维护时,才去考虑整体的代码重构。

如果进行不断的小步迭代,代码的可读性与可维护性就会不断提升。

我感觉代码就像是流水,是在不断变化的,而不是处于根据项目基线实现下的有限状态。在这种流水式的代码演进过程中,随着编码人员的理解不同,代码还会有back and forth,正如这本书中提到的大多数重构都是同时具有正向操作和反向操作的一样。

一种重构过程:

  1. 基于mvc模型,代码包含大量的 data(pojo) 类和 service,而这些 service 常常对代码进行流水账式的胶水操作。
  2. 需要添加新功能时,从service中寻找可复用的方法,没有则添加方法。
  3. 改善胶水代码,提高可读性。特别是长方法,根据单一职责原则,分解方法步骤。
  4. 面向对象程序设计。为 data 类添加功能,移动方法到对应的类中,相似的逻辑通过OOP进行封装和设计。

几个我不太认同的重构方法

  1. NullObject。空集合很适用,因为这个类天然自带”零元”, emptyCollection 就是 NullObject。默认值的填充使用Optional感觉更好,Optional 天然就是解决没有的,使用orElse, orElseGet, or等方法更好,此外还有 map, flatMap 等方法。况且Java 本来就有null这个关键字,就是用来表示没有的。null 和 Optional 以及@notnull等注解可以比较好地解决 NEP 的问题。用在二叉树上,null 表示没有值。用在unknown用户上,Optional 可以避免显式使用if else / 三元表达式,可读性更好,ofNullable(customer).orElse(unknown)。
  2. 方法内抛出异常。方法需要程序员关注超出方法签名的范围,有时需要查看注解才能得知异常。异常应该在方法签名上体现,使用 Result 类更好。

几个开箱即用的重构方法

如果你还没有看过原书,以下是我总结的几个可以快速上手的重构方法,不涉及OOP的设计,可以一试:

  1. Rename Method, Alt + Shift + R, 给方法起一个好名字。
  2. Replace Temp with Query, Alt + Shift + I (inline), 减少临时变量的使用。
  3. Extract Method, Alt + Shift + M, 对于长方法可以改为多个步骤的组合。
  4. 简化条件表达式,选中条件表达式,然后提取成方法。
  5. 代码中不可变的对象改为 final 或者值类型。
  6. 封装集合类,如返回 Collections.unmodifiableList(yourList);

相关文章: