重构
...About 4 min架构重构
重构是什么?(what)
设计模式为重构提供了目标。然而“确定目标”只是问题的一部分而已,改造程序以达到目标,是另一个难题。
重构(refactoring):在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。
重构(名词):提高其可理解性,降低其修改成本;
重构(动词):调整代码组织结构过程;
重构与YANGI
- 如无必要,勿增实体,满足当前业务即可;
重构与软件开发
- 两顶帽子法则
- 实现功能是一顶帽子,重构代码是另外一顶帽子;
- 整个开发过程中来回切换,每次 commit 一顶帽子;
- 自测试代码、持续集成、重构——彼此之间有着很强的协同效应。
重构与性能
相同点
- 目标导向:改进软件系统;
- 迭代进行:不是一次性完成,开发过程多个阶段进行;
不同点
- 目标差异
- 重构:让程序“更容易理解,更易于修改”;
- 性能优化:让程序运行得更快;
- 关注点不同
- 重构:代码实现和结构;
- 性能优化:算法、数据结构、查询优化、资源利用率;
- 影响范围
- 重构:通常针对局部代码和模块修改;
- 性能优化:需从系统多个方面考虑,可能设计代码改动;
- 时间和优先级
- 重构:开发过程中,持续改进;
- 性能优化:系统设计或开发后期,通常在系统功能基本实现后;
为什么重构?(why)
重构目的
- 重构的唯一目的就是 让我们开发更快,用更少的工作量创造更大的价值。
- 好代码的检验标准就是人们是否能轻而易举地修改它。
- 代码被阅读和被修改的次数远远多于它被编写的次数。保持代码易读、易修改的关键,就是重构——对框架而言如此,对一般软件也如此。
重构好处
- 重构改进软件的设计
- 重构使软件更容易理解
- 重构帮助找到bug
- 重构提高编程速度
- “设计耐久性假说”:通过投入精力改善内部设计,我们增加了软件的耐久性,从而可以更长时间地保持开发的快速。
什么时候重构?(when)
Don Roberts 准则:第一次做某件事时只管去做;第二次做类似的事会产生反感,但无论如何还是可以去做;第三次再做类似的事,你就应该重构。正如老话说的:事不过三,三则重构。
何时重构
- 预备性重构:让添加新功能更容易
- 帮助理解的重构:使代码更易懂
- 捡垃圾式重构
- 有计划的重构和见机行事的重构
- 长期重构
- Branch By Abstraction:搞个抽象,抽象代理层;
- 复审代码时重构
何时不重构
- 如果看见一块凌乱的代码,但并不需要修改它,那么就不需要重构它。
- 如果重写比重构还容易,就别重构了。
如何重构?(how)
识别坏味道、测试先行、行为保持的变更动作,是重构的基本功。
- 开展高效有序的重构,关键的心得是:小的步子可以更快前进,请保持代码永远处于可工作状态,小步修改累积起来也能大大改善系统的设计。
- 营地法则:保证每次提交后的代码库一定比之前更健康。
重构的挑战?
- 延缓新功能开发
- 代码所有权
- 重构之后对代码掌控更清晰;
- 不同分支开发合并
- 合并代码可能冲突
- 测试
- 不会改变程序可观察的行为,这是重构的一个重要特征。
- 遗留代码
- 对于历史遗留代码没有单测这个问题,显而易见的答案是**“没测试就加测试”**。
- 每次触碰一块代码时,我会尝试把它变好一点点——至少要让营地比我到达时更干净。如果是一个大系统,越是频繁使用的代码,改善其可理解性的努力就能得到越丰厚的回报。