重构(名词): 对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
重构(动词): 使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构。
重构的关键在于运用大量微小且保持软件行为的步骤,一步步达成大规模的修改。
重构是为了让代码“更容易理解,更易于修改”。这可能使程序运行得更快,也可能使程序运行得更慢。而性能优化只关心如何让程序运行得更快,最终得到的代码有可能更难理解和维护。
重构时不能再添加功能,只管调整代码的结构。
软件开发过程中,可能会发现自己经常变换帽子。做一会儿重构、做一会儿添加新功能,但无论何时都必须清楚自己戴的是哪一顶帽子。
重构是一个工具,可以(并且应该)用于一下几个目的:
“设计耐久性假说”:通过投入精力改善内部设计,我们增加了软件的耐久性,从而可以更长时间保持开发的快速。
在我编程的每个小时,我都会重构。
三次法则:
第一次做某件事时只管去做;
第二次做类似的事会产生反感,但无论如何还是得去做;
第三次再做类似的事,你就应该重构。
预备性重构:让添加新功能更容易
重构的最佳时机就在添加新功能之前。
帮助理解的重构:让代码更易懂
需要先理解代码在做什么,然后才能动手修改。
重构带来的帮助不仅发生在将来——常常是立竿见影。
捡垃圾式重构
如果每次经过这段代码都把它变好一些,积少成多,垃圾总会被处理干净。
有计划的重构和见机行事的重构
预备性重构、帮助理解的重构和捡垃圾式重构——都是见机行事的:并不专门安排时间来重构,而是在添加功能或修复bug的同时顺便重构。
在重构上花一个星期的时间,会在未来几个月里发挥价值。
长期重构
可以让整个团队达成共识,在未来几周时间里逐步解决这个问题,这经常是一个有效的策略。
复审代码时重构
代码复审可以改善开发状况,有助于在开发团队中传播知识,也有助于让较有经验的开发者把知识传递给比较欠缺经验的人,并帮助更对人理解大型软件系统中的更多部分。
结对编程:可以在编程的过程中持续不断地进行代码复审。
怎么对经理说
如果这位经理懂技术,能理解“设计耐久性假说”,那么向他说明重构的意义应该不会很困难。
当然,很多经理和客户不具备这样的技术意识,他们不理解代码库的健康对生产效率的影响。这种情况下就:不要告诉经理!
何时不应该重构
如果重写比重构更容易,就别重构了。
重构会遇到以下几个挑战:
延缓新功能开发
重构的意义不在于把代码库打磨得闪闪发光,而是纯粹经济角度出发的考量。
我们之所以从重构,以为它能让我们更快——添加功能更快,修复bug更快。
代码所有权
代码所有权的边界会妨碍重构,因为一旦我自作主张地修改,就一定会破坏使用者的程序。
分支
特性分支对重构的阻碍比较严重。
测试
绝大多数情况下,如果想要重构,得先有可以自测试的代码。
遗留代码
重构可以很好地帮助我们理解遗留系统。
数据库
重构极大地改变了人们考虑软件架构的方式。
演进式架构是一门仍在不断发展的学科,架构师们在不断探索有用的模式和实践,充分发挥迭代式架构决策的能力。
重构的第一块基石是自测试代码。
如果一个团队想要重构,那么每个团队成员都i需要掌握重构技能,能在需要时开展重构,而不会干扰其他人的工作。
自测试代码、持续集成、重构——批次之间有着很强的协同效应。
有这三个核心实践打下的基础,才谈得上运用敏捷思想的其他部分。
重构可以帮我写出更快的软件。短期看来,重构的确可能使软件变慢,但它使优化阶段的如软件性能调优更容易,最终还是会得到好的效果。