重构第二版的变更

重构第一版和第二版之间变更的简要概述

2018年9月5日

从最广义的角度来说,第二版的结构遵循第一版的结构。这并不奇怪,因为第一版非常成功,我可能也会继续使用有效的方法。

第一版以四个叙事章节开头,这些章节也出现在第二版中。所有这些都遵循原书的广泛形式。

开头的示例改变了其领域,因为现在没有多少人熟悉视频商店。重构的流程基本相同:分解成函数,将计算与格式化分离,使用多态性按类型组织计算。

原则和代码坏味道章节都进行了彻底的修改。其中很多内容保留了下来,也很多内容发生了变化。我估计大约四分之三的内容发生了变化,但这只是直觉,而不是基于现实的测量。测试章节必须完全重写,特别是由于从 Java 到 JavaScript 的更改。

在这些介绍性章节之后,我继续介绍目录,我一直认为它是本书的核心。我将在稍后详细介绍目录的变更,但一个值得注意的结构变更是我将一些重构放在一起,构成一个初始章节,其中包含我认为首先学习的一组好的重构。

我删除了后面的章节,这些章节探讨了一些更切题的问题。我认为它们在第一版中有效,但现在我认为最好在我的网站上发布这样的文章。这也是我从目录中删除四个“大型重构”的原因。大型重构一直与大多数重构略有不同,我确实觉得这些示例在我的网站上通过文章展示效果更好。

目录变更

那么目录发生了什么变化呢?以下表格显示了原始 68 个重构的命运。 [1]

第一版中重构的命运
名称页码命运替换
添加参数275已替换➜ 更改函数声明
将双向关联更改为单向关联200缺失
将引用更改为值183保留
将单向关联更改为双向关联197缺失
将值更改为引用179保留
折叠层次结构344保留
合并条件表达式240保留
合并重复的条件片段243已替换➜ 滑动语句
分解条件238保留
复制观察到的数据189缺失
封装集合208保留
封装向下转型308缺失
封装字段206已替换➜ 封装变量
提取类149保留
提取接口341缺失
提取方法110已替换➜ 提取函数
提取子类330已替换➜ 使用子类替换类型码
提取超类336保留
提取变量124保留
形成模板方法345缺失
隐藏委托157保留
隐藏方法303缺失
内联类154保留
内联方法117已替换➜ 内联函数
内联临时变量119已替换➜ 内联变量
引入断言267保留
引入外部方法162缺失
引入本地扩展164缺失
引入空对象260已替换➜ 引入特殊情况
引入参数对象295保留
移动字段146保留
移动方法142已替换➜ 移动函数
参数化方法283已替换➜ 参数化函数
保留整个对象288保留
向上移动构造函数主体325保留
向上移动字段320保留
向上移动方法322保留
向下移动字段329保留
向下移动方法328保留
删除对参数的赋值131已替换➜ 拆分变量
删除控制标志245已替换†➜ 使用 break 替换控制标志
删除中间人160保留
删除参数277已替换➜ 更改函数声明
删除设置方法300保留
重命名方法273已替换➜ 更改函数声明
将数组替换为对象186缺失
将条件替换为多态性255保留
将构造函数替换为工厂方法304已替换➜ 将构造函数替换为工厂函数
将数据值替换为对象175已替换➜ 将基本类型替换为对象
将委托替换为继承355缺失
将错误代码替换为异常310保留†
将异常替换为测试315已替换†➜ 将异常替换为预检查
将继承替换为委托352已替换➜ 将超类替换为委托
将幻数替换为符号常量204已替换†➜ 替换幻数字面量
将方法替换为方法对象135已替换➜ 将函数替换为命令
将嵌套条件替换为保护子句250保留
将参数替换为显式方法285已替换➜ 删除标志参数
将参数替换为方法292已替换➜ 将参数替换为查询
将记录替换为数据类217已替换➜ 封装记录
将子类替换为字段232已替换➜ 删除子类
将临时变量替换为查询120保留
将类型码替换为类218已替换➜ 将基本类型替换为对象
将类型码替换为状态/策略227已替换➜ 使用子类替换类型码
将类型码替换为子类223保留
自我封装字段171已替换➜ 封装变量
将查询与修改器分离279保留
拆分临时变量128已替换➜ 拆分变量
替换算法139保留

† 仅限网络版

标记为保留的重构在第二版中以相同的名称存在。标记为缺失的重构不在新版中。我从新版中删除重构的原因有很多,我可能会扩展这篇文章,在将来讨论其中的一些原因。标记为已替换的重构在新版中以不同的名称存在。其中一些只是重命名,例如,我将“拆分临时变量”更改为“拆分变量”。大多数是轻微的泛化,例如,将“提取方法”更改为“提取函数”。许多这些泛化反映了重写中面向对象程度较低。在某些情况下,第一版中的几个重构被合并:例如,添加参数、删除参数和重命名方法都被“更改函数声明”替换。与我删除的重构一样,我可能会在将来扩展这篇文章,讨论一些具体案例。 [2]

新版包含 15 个完全全新的重构,它们不是现有重构的泛化或重命名。它们是

将函数合并到类中
将函数合并到转换中
将语句移动到函数中
将语句移动到调用者中
删除死代码
重命名字段
重命名变量
将命令替换为函数
将派生变量替换为查询
将内联代码替换为函数调用
将循环替换为管道
将查询替换为参数
将子类替换为委托
返回修改后的值
拆分阶段

我意识到,仅凭名称并不能说明这些新重构的作用,或者泛化后的重构与第一版中的重构有何不同。我会及时更新 在线目录,以提供更多相关信息。


脚注

1: 68 不包括原书中的四个“大型重构”。正如我之前提到的,我认为这类主题最好以文章的形式在网上发布。

2: 我是否这样做取决于读者是否对此感兴趣,以及我如何将此事优先于未来几个月我想写的其他内容。