来自 技术 2019-04-17 00:00 的文章

重构不完全指南!

八年Java开发的感悟:什么才是程序员的立身之本>>>   

首发公众号《andyqian》,期待你的关注!

前言

程序员在职业生涯中,不可避免的就是接手老项目,重构历史项目。事实证明,不论是老项目还是新项目都会遇到这种情况,不信你去看看一周前自己写的代码,是不是有很大的改进空间?对于新入行的朋友们也要做好准备,以后也或多或少会面对这样的情况。在面对这样的情况时,不管你接手前是多么不愿意,接手后怎么破口大骂,甚至有过无数次想放弃的念头。但问题始终摆在那,始终需要面对。在最近一段时间里,一直在进行项目重构方面的工作,项目不大,但在重构过程中,依然有一些感受,想借此机会分享出来。不过,现在去看看已经重构过的代码,依然有很大的改进空间。

在介绍重构方法之前,下面几个原则是非常重要的,甚至在重构时都是需要时刻紧记。否则在重构过程中,一定会让你十分痛苦,甚至会多几次想放弃的念头。

以最小单元为重构点。也就是说:不要一上来看这不顺眼,看那也不顺眼,改了一通,到最后项目都运行不起来。

对于重构后的方法,功能点,一定要验证通过后再重构下一个。该写的单元测试一个也不能少。

对外提供的接口,无论是Rest接口还是RPC接口,用冗余的方式进行重构,意思是说:对已经对外提供的接口,在保证正确的前提下,内部怎么重构都可以,但不要修改对外的数据结构。或者采用升级接口版本的形式,将老接口标记为过时,老接口与新接口并存运行的形式。

理清流程

之所以将其放至首位,因为我觉得这是在动代码之前最重要的步骤。理清楚这个服务的职责,主要流程,关键步骤,关键状态的转换是非常重要的。如果之前有设计文档描述了这些内容就再好不过了。我们只需要对照着设计文档先对系统有个宏观的印象,再对照着文档与代码进行一步步查看一遍,这一遍并不需要很仔细,最主要是对涉及到的对象,数据流向有初步印象即可。如果没有任何文档,或者文档已经和代码完全不匹配时,我们也只能硬着头皮通过代码来还原文档了。这时我们可以先通过代码的执行流程,画时序图理清楚服务内部交互的方式,可以通过画类图理清楚类与类之间的关系,可以通过画流程图来理清楚数据的走向。让比较具体的代码形式转换为更抽象化的文档形式。首先我必须承认,这是一个非常痛苦的过程,但这算的上是一个有效的办法。同时这也是我做的不够的地方,接到任务后一心想着钻进代码改这改那,却忽视了这最重要的步骤。

找出坏味道

通过上一步,对我们需要重构的项目基本有了清晰的轮廓。到这一步,我们最主要的职责是找出事件入口并体验。这里指的事件是指暴露形式,如:Rest接口,RPC服务,定时任务等形式。我们只有体验了流程,才能找出代码中的坏味道。如果对项目完全不熟悉或者一知半解的强烈推荐用debug的模式一步一步看看代码的执行过程,避免发生重构后造成服务不可用的惨案。这时如果遇到觉得需要重构的点,可以先记录下来,直到debug完成后。这时记录下来的点,就是你需要重构的地方。如果你发现,重构完这些点都足以重新写了,那么,刚才的那一遍debug对你理解流程以及注意事项是有帮助的。

剔除坏味道

完成前两步后,我们都应该对流程,数据流向都非常熟悉了。现在来修改代码再合适不过,但在修改前,我依然建议大家用冗余的方式进行修改。也就是说:此时我们还不要急着删除原来的代码,建议重新起一个单独新的内部方法,进行编写,单元测试,在入口修改为重构后的方法,再进行集成测试,验证,直至上线。重构代码线上验证通过后,再删除老代码也未尝不可。我们在软件开发时,崇尚“小步快跑,快速迭代”的迭代思维,同样的,我建议重构也应该是这样的,不建议修改了非常多或全部重构完成再进行验证,这样无论验证时间还是验证范围都是不可接受的。

验证

写单元测试是一个神奇而无味的工作,神奇在于它能挖掘出很多低级,甚至想抽自己巴掌的错误,无味在于大家认为这是一项毫无技术难度的苦差事。殊不知在重构项目时,单元测试也发挥了及其重要的作用,我们可以通过单元测试来熟悉项目,熟悉流程,熟悉每一个方法,熟悉每个数据的走向。在重构完成后,我们也应该编写单元测试进行验证,在代码修改后,我们也应该对单元测试进行修改,进行验证,保证代码与单元测试是一一对应且同步的。

当然,重构过程中,除了单元测试外,也需要自己进行功能性测试,更需要测试同学的功能测试,边界测试,性能测试等等。总之,重构过程,是一个合作的过程。

最后

其实不论重构项目,还是入职新公司熟悉项目,都可以使用上面的方法进行实践。通过上面这些步骤,基本上能对项目加深影响,能够让自己对项目有个更深层次的理解。现在回顾看看自己前一个月,前一周的代码都有很多需要修改,值得精进的地方。嗯,代码需要迭代,系统需要重构,你我也需精进!

嗯,唠叨了这么多,也算是对最近重构工作的复盘吧!

相关阅读:

《谈谈 996 背后的现象》

《说说Java位运算》

《软件之路》

《浅谈 Java JPDA》

扫码关注,一起进步

个人博客:http://www.andyqian.com