前言
代码重构一直以来都是代码人经常要关注和进行的工作,我相信能写出一手好代码应该是每一个代码人的目标。那么什么样的代码是好代码,而我们平时写的代码还有哪些可以重构的地方呢。我在《重构-改善既有代码的设计第二版》找到了一些答案。由于内容较多,并且全书无一废话,价值巨大,所以这里我只列一个重构清单,更具体的还望各位同仁去翻阅书本。相信你也一样会收获巨大。
一、代码重构的目标
目标1:好的代码应该能够让人清晰易懂
为了使得代码清晰易懂,我们常需要做的几件事是:
- 使用合适的命名,包括函数命名,变量命名、字段命名
- 提炼函数,使得函数更小,每个函数只做一件事
- 计算和查询分开
- 拆分阶段,将一个长函数或者计算复杂的过程拆成几个部分
- 搬移函数,把相关的函数和数据放置到一起
- 把过多的参数封装成对象
- 使用管道函数map/filter
目标2:好的代码修改起来应该要容易
代码修改起来之所以困难,通常是存在着变量繁多,数据和函数多处使用,各种条件混合、数据多处调整,代码重复等问题,因此常需要做的几件事是:
- 提炼函数,将重复的代码去掉
- 用查询代替变量,避免变量贯穿整个上下文
- 提炼类,将数据和数据操作放置到一起,特别是修改一个东西就要修改多处的情况
- 用多态代替条件
目标3:好的代码应该让人能够只在一处地方就能找到相关数据和操作
- 提炼类
- 搬移语句,将变量和使用方放置在一起
目标4:好的代码应该比较简洁
- 移除中间人
- 使用管道函数
- 隐藏委托关系
二、代码重构的准则
准则1:代码重构的过程是个循序渐进的过程,尽量不要一次性完成,因为这会造成巨大的稳定性风险
准则2:代码重构的核心是使得代码更加清晰易懂且修改容易,所以很多时候性能不是关注的重点。在大多数情况下,性能并不是阻碍软件使用的瓶颈,坏代码才是。
准则3:重构过程中应该要伴随着自动化测试
三、对于坏味道的代码优化清单(书中原意摘取)
- 神秘命名 函数改名、变量改名、字段改名
- 重复代码 提炼函数、移动语句、函数上移
- 过长函数 提炼函数、以查询取代临时变量、引入参数对象、保持对象完整、命令取代函数、分解条件表达式、以多态取代条件表达式、拆分循环、拆分阶段
- 过长参数列表 以查询取代参数、保持对象完整、移除标记参数、使用函数组成类
- 全局数据 封装变量,将全局数据用一个函数包装起来,至少可以看见修改他的地方,并开始控制对他的访问
- 可变数据 封装变量、拆分变量、移动语句、提炼函数、条件查询、修改函数分离、移除设值函数、以查询取代派生变量、函数组成类、函数组合成变换、将引用对象修改为值对象
- 发散式变化 拆分阶段、搬移函数、提炼函数、提炼类
- 散弹式修改 搬移函数、搬移字段、函数组成类、函数组合成变换、拆分阶段、内联函数、内联类
- 依恋情结 搬移函数、提炼函数
- 数据泥团 提炼类、引入参数对象、保持对象完整
- 基本类型偏执 对象取代基本类型、子类取代类型码、多态取代条件表达式
- 重复的switch 以多态取代条件表达式
- 循环语句 以管道取代循环(filter、map、reduce)
- 冗赘的元素 内联函数、内联类、折叠继承函数
- 夸夸其谈通用性 内联函数、内联类、函数声明
- 临时字段 提炼类、搬移函数、引入特例
- 过长的消息链 隐藏委托关系、体联函数、搬移函数
- 中间人 移除中间人、内联函数、
- 内幕交易 搬移函数、搬移字段、隐藏委托关系、委托取代子类、以委托取代超类
- 过大的类 提炼类、提炼超类、以子类取代类型码
- 异曲同工的类 改变函数声明、搬移函数、提炼超类
- 纯数据类 封装记录、移除设值函数、搬移函数、体联函数
- 被拒绝的遗赠 函数下移、字段下移、以委托取代子类、以委托取代超类
- 注释 提炼函数、改变函数声明、引入断言
总结
重构和写出好代码是衡量一个代码人水平的重要标准,而这本书中每一点重构的方法都配备了相应的例子,清晰易懂。当我们发现代码难以读懂、修改起来费劲的时候,那一定是到了重构的最佳时机,最痛的点了。这本书应该要成为代码人身边的案头书,时时翻阅,期待大家都能写出好代码。