摘要:让我们再回到重构的基本概念,思考我们需要怎样的重构辅助服务。 一、背景
代码重构是每一位开发者最熟悉不过的字眼,其出现通常伴随着开发过程。在程序开发、迭代与演进的漫漫长路中,某次不经意的修改就可能破坏程序原有的设计与结构,造成代码结构的流失,而这种流失是具有累积性的,若未及时发现与重构,程序就会逐渐腐烂甚至变质,形成巨大的历史债务。其实重构就好比收拾房间,如果我们天天打扫,那么每天花3分钟就能打扫干净,可如果一个月不打扫,你想想需要多久才能打扫完。
既然代码重构在开发过程中这么重要,怎么能没有相应的服务来支撑它呢?我们能不能开发出相应的“扫帚”辅助我们每天打扫房间?亦或是“扫地机器人”自动的帮我们打扫一个月未收拾的房间?
带着上述疑问,让我们再回到重构的基本概念,思考我们需要怎样的重构辅助服务。
1. 什么是重构如此书中所说,所谓重构(Refactoring)是这样一个过程:在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。这里的重构有两层含义,一个名词含义,一个动词含义:
重构(名词):对软件内部结构的一种调整, 目的是在不改变软件可观察行为的前提下,提高其可理解性, 降低其修改成本。
重构(动词):使用一系列重构手法, 在不改变软件可观察行为的前提下,调整其结构。
至此,我们应该明白,一款好的重构辅助服务应该至少兼具不变与变两个特征:不改变软件可观测行为;优化代码结构,降低修改成本,提高可理解性。
2. 什么时候重构(何时应做怎样的重构)就重构时机问题,业界也有比较激烈的讨论,有人认为重构应该随时随地地进行,不应该为了重构而重构,就比如我在添加新功能时、修补错误时、或者复审代码时都可以进行重构,我们暂且称之为“开发时重构”,也有人认为“添加新功能”和“重构”是两顶帽子,在添加新功能时,就不应该修改既有代码,只管添加新功能,而在重构时,就不能添加功能,只管改进程序结构,一次只做一件事,我们暂且称之为“维护式重构”。我个人认为这两种说法并不矛盾,真正好的重构应该是两者的有机结合。
如上图所示,红色范围是我认为比较好的重构实践。
我认为无论在做新功能开发时还是在做老版本维护时,都适合做代码重构,只是适合的重构粒度不同而已。对于开发时重构,比较适合做个人级小范围的微重构,这种重构往往影响范围小,且较为简单,不会对开发增加工作难度,例如“重命名”、“函数提取”等原子重构;对于维护时重构,比较适合做架构级大范围的复杂重构,这种重构往往是为了解决项目代码中遗留的技术债务,且通常和代码坏味道的消除结合在一起,例如依恋情结(Feature Envy)、数据泥团(Data Clumps)等,而这些坏味道的重构往往由一系列的重构原子操作组合而成。当然,最好将重构工作尽可能多地做在开发阶段,尽量减少新增代码对已有设计与架构的破坏。
看到这里,我们是否有些似曾相识,这不就对应了上文中提到的“扫帚”以及“扫地机器人”在实际重构工作中的应用?
3. 为什么需要代码智能重构服务使用过现代IDE开发代码的同学们应该都知道,以IntelliJ IDEA为代表的很多IDE多少都自带一些重构功能,但目前为止,这些重构都是例如“重命名”、“函数提取”等原子性重构,只对重构过程提供了部分支持,绝大部分的代码、架构坏味道重构工作仍然得靠手工完成,就好比你需要打扫一个月未打扫的房子,但手中只有一把扫帚一样。Kent Beck 说过:“手工重构仍然是很耗时的工作。正是这个简单的事实造成了很多程序愿不愿意进行重构,尽管他们知道自己应该重构,但毕竟重构的成本太大了。如果能够把重构变的像调整代码格式那么简单,程序员自然也会乐意像整理代码格式那样整理系统的设计。而这样的整理对代码的可读性、可复用性和可理解性,都能带来深远的正面影响。”正因如此,一款智能的、可以帮助开发者发现代码、架构中的坏味道并且引导开发者完成代码重构的服务尤为重要。
二、Devops全流程下的重构服务需求