欢迎光临BDM
一枚菜鸟码农的成仙之路

《重构——改善既有代码的设计》重构方式汇总

软件学习初期很早就听到了“重构”,后来工作中也经常“用到”,但是却一直缺乏了结构化的指导思想,使得大部分重构经历中均有痛苦的回忆而茫茫然不知其所以。《重构》这本书就恰好解决了方向和依据的问题,达到了知其然且知其所以然的效果,从重构原因、切入点、重构手法都有详细的介绍,甚至还简要提到了如何使领导相信重构的好处。

这本书写于近 20 年前,采用旧版本的 Java 语言描述,但不愧于“经典”的盛名,书中的思想现在仍让我受益匪浅。本文依据我的经验,简要的概况《重构》(熊杰2009年译本)一书中第六章至十四章提到的重构手法,以作读书回顾。标题部分来源于原作者翻译,部分翻译名称采用 C 语言描述,如函数、字段等,其他语言需要进行适当的对应。

第六章 重新组织函数

本章主要是针对方法进行整理,优化局部细节。本章中可能会有一些看似冲突的手法存在,如 Inline Temp(6.3)和 Introduce Explaining Variable(6.5)做的几乎是相反的事情,但正是因为这两者的有机结合才使代码达到更易读更辨识的层次。不用吝啬重构,试着找到最完美的答案吧!

6.1 Extract Method(提炼函数)

动机

过长函数、解释局部代码逻辑

做法

创建一个函数,将方法内局部代码提炼到一个额外方法里。注意妥当地命名方法和处理方法内局部变量。

6.2 Inline Method(内联函数)

动机

多余的委托、减少间接性

做法

逆向提炼函数,将额外的方法融合至调用方法里。

6.3 Inline Temp(内联局部变量)

动机

为了辅助其他重构手法如 Replace Temp With Query(6.4)而解决临时局部变量,将其内联化

做法

将临时变量赋值语句的等式右边的内容移至临时变量的调用处,删掉该临时变量。

6.4 Replace Temp With Query(以查询取代临时变量)

动机

为了辅助其他重构手法如 Extract Method(6.1)而解决临时局部变量,将其替换成对额外方法的调用

做法

将临时变量的系列赋值语句提炼到一个额外的方法中,将该临时变量的调用改为对额外方法的调用,并删掉该临时变量。

6.5 Introduce Explaining Variable(引入解释性变量)

动机

解释过长的局部代码逻辑,如条件逻辑、三元运算符等,和 Extract Method(6.1)有异曲同工之妙

做法

新增一个临时局部变量用于替代原本过长的逻辑,变量名应有足够解释的作用。

6.6 Split Temporary Variable(分解临时变量)

动机

被赋值两次及以上的临时变量使代码易于混淆,难以理解

做法

新增一个临时变量用以取代临时变量的第二次赋值及调用

6.7 Remove Assignments to Parameters(移除对参数的赋值)

动机

对方法的参数进行赋值使代码易于混淆,难以理解

做法

新增一个临时变量用以取代方法的参数的赋值及其后的调用

6.8 Replace Method with Method Object(以函数对象取代函数)

动机

局部变量耦合太高无法使用 Extract Method(6.1)

做法

先创建新类,将欲使用 Extract Method(6.1)的代码块移入新类的新方法中,再将新方法中缺失的变量添入到新类的字段及构造方法中。

6.9 Substitute Algorithm(替换算法)

动机

用新算法替换旧算法

做法

确保你已经正确理解了旧算法在做什么,然后用更好的算法替换他。

第七章 在对象之间搬移特性

本章主要是对类与类的关系进行优化,如何正确处理类之间职责的关系等。

7.1 Move Method(搬移函数)

动机

一个类的方法对另一个类的对象有更多的依赖

做法

将原方法搬移到新类中,将原类的属性当成参数传入,原类的方法采用委托的方式进行保留,或者解决依赖关系后移除。

7.2 Move Field(搬移字段)

动机

一个类的属性更多地被另一个类使用、配合 Move Field(7.1)

做法

将原属性搬移到新类中,将对原类该属性的调用采用委托的方式进行保留,或者解决依赖关系后移除。

7.3 Extract Class(提炼类)

动机

一个类有太多的方法和属性、不同的子类重写了不同的方法(类的职责太多)

做法

将原类的一部分属性和方法转移到一个新类中,将新类对象成为原类的一个属性,然后将原类的方法采用委托的形式调用新类对象的方法,直至解决依赖后删除。

7.4 Inline Class(将类内联化)

动机

一个类有太少的方法和属性、总是和另一个类耦合、没有独立的职责、几乎全部由委托组成

做法

反向 Inline Class(7.4),将类的属性及方法嵌入至目标类中

7.5 Hide Delegate(隐藏委托关系)

动机

客户类通过委托类来调用另一个对象

做法

在服务类中新增委托关系将实际委托类包装起来,使得客户类不会获取委托类的对象而改为由服务类提供所委托的功能。

7.6 Remove Middle Man(移除中间人)

动机

一个类做了太多简单的委托而几乎没有自己的功能,通常是由其他重构动作造成该结果

做法

删除该服务类(实则为委托类),由客户类直接调用受托类

7.7 Introduce Foreign Method(引入外加函数)

动机

对于无法修改的类,想增加它的功能

做法

在客户类中新增方法,将服务类作为参数传入(作为标记和声明),在该方法中实现待新增的功能

7.8 Introduce Local Extension(引入本地扩展)

动机

Introduce Foreign Method(7.7)无法处理的情况,比如该功能需被多个客户类使用

做法

新增服务类成为原服务类的子类或者包装类,该新的服务类中实现该功能

本文遵守知识共享署名-相同方式共享 4.0 国际许可协议,未经允许不得转载BigDickMan » 《重构——改善既有代码的设计》重构方式汇总

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

联系我们GitHub