重构不是一项独立计划的活动,而是应该 持续、见机行事 地融入日常编程工作中的关键实践。
重构的时机类型(见机行事的重构)
大多数重构活动是 见机行事(见机行事的重构) 的,它们是在添加新功能或修复 Bug 的过程中自然发生的。来源描述了以下几种常见的重构时机:
预备性重构:让添加新功能更容易
这是重构的 最佳时机 之一。
- 动机: 当程序员想要给程序添加一个特性时,如果发现现有代码结构不佳而难以进行修改,就应该 先重构那个程序,使其更容易添加该特性,然后再添加特性。
- 效益: 预备性重构就像“先往北开 20 公里上高速,然后再向东开 100 公里”,它能确保你以最快的路径到达目的地,从而提高编程速度。
- 示例: 如果发现一个函数只差几个字面量的值就能满足新需求,应使用 函数参数化 重构,而不是复制整个函数,以避免重复代码。
函数参数化(Parameterize Function)的目的是 用一个通用的函数取代一组相似的函数。如果多个函数的逻辑非常相似,但它们之间仅有少数 字面量值 存在差异,那么就可以通过引入参数来将这些差异值抽象出来,从而将这些相似的函数合并为一个函数
帮助理解的重构:使代码更易懂
重构是理解代码工作的有力工具。
- 动机: 在修改代码之前,程序员需要先理解它。一旦需要思考“这段代码到底在做什么”,就应该自问:能不能重构这段代码,令其一目了然?。
- 实践: 这可能包括给一两个变量改名(如使用 变量改名),使它们更清楚地表达意图,或将一个长函数拆成几个小函数(如使用 提炼函数)。
- 效果: 重构将程序员脑海中的理解转移到代码本身。Ralph Johnson 称之为“扫去窗上的尘埃”,使程序员能够看到隐藏在混乱背后的设计机遇和更高层面的认识。
捡垃圾式重构
这种重构旨在 清理代码库中的坏味道,但要平衡其投入和产出。
- 原则: 如果发现的“垃圾”(如逻辑不必要地复杂、两个函数相似可被合并)很容易重构,应 马上重构;如果需要花一些精力,可以记下来,完成当前任务后再回来重构。
- “营地法则”: 至少要让营地比你到达时更干净。每次经过一段代码时,即使只是做一点点清理工作,随着时间的推移,代码库的健康状况也会积累式地得到改善。
计划性重构和持续性
明确不要将重构视为与编程割裂的活动,强调它应该是编程流的一部分。
- 日常化实践: 程序员在编程的 每个小时 都会做重构。项目计划上通常 没有专门留给重构的时间,绝大多数重构都在做其他事的过程中自然发生。
- 有计划的重构: 只有在团队过去长期忽视了重构,或者某个区域的问题已经累积长大,需要花一个星期或更长时间来解决时,才可能需要专门安排时间进行 有计划的大规模重构。这种计划性重构应该很少见,大部分重构应该是不起眼的、见机行事的。
核心原则:小步快跑与测试保障
重构的时机和方式都紧密围绕两个核心原则:
- 频繁测试: 重构的前提是拥有一套 可靠的、自我检验的测试集。程序员应该频繁运行测试,通常对正在处理的代码,每隔几分钟就要运行一次,每天至少运行所有测试一次。永远不应该在测试失败时进行重构。
- 小步前进: 无论何时,重构都应该以 微小的步伐 修改程序,并保持代码始终处于编译通过和测试通过的 可工作状态。小的步子可以更快前进,因为即便犯错也能轻松发现和修复,并能回滚到上一个可工作的提交点。
何时不应该重构
重构虽有巨大价值,但并非没有例外。有几种情况不值得进行重构:
- 不需要修改的代码: 如果看见一块凌乱的代码,但 并不需要修改它,那么就没有必要重构。如果代码能够正常工作,并且不会再被修改,那么完全可以不去重构它。
- 重写更简单: 如果重写比重构还容易,就 别重构了。这需要良好的判断力与丰富的经验来决定。
三次法则
针对重复代码,Don Roberts 提供了重构的准则 “三次法则”:
- 第一次 做某件事时只管去做。
- 第二次 做类似的事会产生反感,但无论如何还是可以去做。
- 第三次 再做类似的事,就应该重构。
总结
重构的最佳时机不是等待一个完美的大时机,而是 只要修改代码就重构,特别是当添加新功能或修复 Bug 的工作被现有代码结构所阻碍时。这种持续、微小、有测试保障的重构模式,正是保持软件设计耐久性,并最终提高编程速度的关键。
- Author:CoderWdd
- URL:https://www.wuinsights.top//article/17dc9ab0-a9cd-4ae1-ae53-a8bfc68ed78f
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts