最近几年经历了好几个项目的重构,随着发量的日益减少渐渐的对于重构有了一些思考。
一、重构的必要性以及基本套路
1.1、为什么要重构?
在重构前,首先要明白重构的目标,如果不重构行不行,不重构不也照样跑的好好的嘛,在我今年没有参与最近所重构的一个项目我也是不太重视重构的。但是现在我觉得重构是很有必要的,引起重构主要有两方方面的原因,一个是外部原因,一个是内部原因。
外部原因就是程序采用的基础设施官方已经不维护,所带来的程序无法使用的风险。比如底层框架、技术、所购买的第三方服务后续可能无法正常使用。
内部原因就是用户抱怨产品体验感不好或者代码混乱,带来后续无法快速迭代响应需求。
内部原因看起来好像并不是痛点甚至不是很必要,但是如果重构前做一个需求的工期需要2个星期,重构后同样一个需求的工期是1个星期,那么你觉得重构还是非必要的嘛。又或者再举一个列子,一个导入500条数据,每条数据又需要关联几百条数据,其中需要做很多验证,一个导入流程下来耗时1分钟甚至超过1分钟导致前端触发超时机制,这就已经影响用户体验了。现在对这个导入做业务上的重构,流程规定导入只需要导入500条数据,而启用每一条数据的时候,再将这一条数据关联的几百条数据插入数据即可,一下子就相当于为导入分流了,导入性能瞬间达到300毫秒内。这个时候你是不是觉得重构很有必要了。
1.2、什么是重构
重构,是一种对软件内部结构的改善,目的是在不改变软件的可见行为的情况下,使其更易理解,修改成本更低。也可以理解为在保证功能不变的前提下,利用设计思想、原则、模式、编码规范等理论来优化代码,修改设计上的不足,提高代码质量。
这是百度百科上的原话,总结下来,就是不要破坏原有功能,同时按照代码规范,提高代码质量和扩展性。
1.3、重构的目标
重构的目标很重要,只有目标明确了,才能确定的重构的方向,基于目标定范围。重构目标我大概也可以分为两个,一个是业务重构目标,另外一个是程序代码质量目标。
业务重构目标就是某些业务流程是不是可以不用那么耦合,这样一旦出现问题,那么影响也小。这个包含前端、客户端界面上的流程控制也包含后端业务模块代码的耦合。
程序代码质量目标就是是不是可以替换老架构,提高程序性能。
1.4、重构的范围
重构的目标确认下来以后,那么重构的范围就非常清晰了。如果重构的只是程序代码质量,那么只需要翻译即可。如果仅仅只需要重构业务流程,那么只需要改对应的前后端代码。总之要定义好重构的范围,不要出现额外扩展重构,导致出现额外的工作量。重构的时候需要确定前端、后端、数据库是否有变动,甚至是重构某些模块还是全系统都重构。一旦对这些心里有谱了,那么后面只需要按计划执行即可。
1.5、重构的验证方式
重构的验证方式这个比较重要,如何保证重构出来的是正确的了,这个时候就需要去测试验证了。由于我重构的项目上下游系统交互较少,所以大部分只需要考虑自己的系统就好,只要测试大哥将场景覆盖到位,问题基本不大。但是如果上下游交互系统涉及10多个,那么为了减少对上下游系统的影响,可以双验证,这个比较复杂,感兴趣的可以留言讨论。
1.6、重构的上线计划
重构也算是一个比较大的迭代版本了,但凡程序有代码改动,那么上线就需要慎重,以免出现bug给用户带来不好的体验。这个时候有一种发布概念就可以降低这个重构迭代发布所带来的风险,那就是灰度发布与版本切换了。
灰度发布就是只让一部分用户可以使用这部分重构的代码,这样即使出bug了,那么影响也小。具体来说就是如果是B端产品,那么就是我只让指定商户可以使用这部分新功能,如果是C端用户,那么我可以根据IP指定用户使用新功能。
版本切换就是如果用户使用重构的代码出现bug了,且意见比较大时,通过版本切换,可以快速让他回到老版本,实现线上业务无阻塞。
二、重构的其他注意事项
** 2.1、重构的技巧**
这个这里我就简单提提,大多就是要明白项目里面那些代码块已经影响到程序的质量以及后续需求的扩展、线上问题的排查。
a、为了能让自己和团队几个月以后都还能明白这块代码是干啥的,好的注释是必不可少的。
所谓好的注释就是你这个注释加上以后别人就能立马看懂这块代码背后的业务逻辑,而不是说加了注释就行。
见过有些注释加了往往误导人,还不如不加。
b、线上的问题是极其复杂的,所以有时候为了方便后续排查线上问题,好的日志是必不可少的。
所谓好的日志是非常重要的,因为有时候程序的异常的堆栈信息没有完整的输出,那么这个时候日期就能排上大用场了,好的日志一眼就能让你发现报错的地方,设置可以直接拿来运行、调试发现报错的地方。
当然有时候日志也不是胡乱加的,日志加多了反而会造成线上日志控制台不好排查,所以这是每一次排查线上问题的过程中,日志也是需要慢慢的调整的,将日志加在最容易出错的几个地方。
c、从业务上找到共性联想到代码进行一个抽取。
这个有点抽象了,打个比方,比如我们小时候看的《西游记》的九九八十一难,基本每一关都是:妖怪出场、师傅被俘、徒弟打妖怪、妖怪被神仙收走。想一想如果运用到代码里面会怎么写,是么每一个妖怪都有自己的一套流程嘛,如果是这样的话,后续维护起来就很麻烦了。
其实这里面就妖怪出场不同,其余的基本一样,这个时候我们可以将后续三个步骤的固定,只需要不断的写第一个步骤妖怪出场就好,这样就节省了后续三个模板的代码以及每次改动只需要改动第一个模板的代码就好,风险点也少,其实这里面用的就是设计模式里的模板模式,运用这个模式的时候需要对业务很熟悉,具体强大的业务归纳和抽取能力。
这个估计有点难以做到,我也是最近从公司的一位扫地僧级别的耳濡目染才明白的,真的非常幸运了。
d、关于重构方面的文档留存,方便后续复盘。
这点没啥好说的,主要是为了后续有记录复盘,还有就是方便新来的同学快速对本次项目重构的一个了解。
当然我这里只是提了几个常见的关于重构方便的小技巧,真正对这个重构感兴趣的同学,可以去看看《重构改善既有代码的设计》一书,相信你会受益良多的。
**2.2、关于重构的预期 **
说点非技术的,既然重构,那么肯定就是要有一个预期结果的。而这个预期结果也是可以具体指标化的,有了这些指标就可以判断此次重构的结果,可以用来跟上级汇报。
a、某某接口响应速度达到多少毫秒。
b、重构后线上bug率与之前是否减少。这里也需要补充下,这个指标是需要上线一段时间后才能按照这个执行的,刚开始的时候也要跟业务方谈好,重构上线可以允许出现几次中等bug,如果在约定好的次数范围内,那么也是可以的。
c、重构后对用户在流程上的体验。
d、程序质量的提升以及后续维护的扩展性。** **
前面两个还是比较形象化的,后面两个就比较抽象了,也不太好定标准。
2.3、关于重构的内部开发策略
总结下来就是内紧外松,这个也是我在看了有一篇文章下来才明白原来我们也是如此。对外的时候,我的老大也跟业务方和产品降低了重构的预期。对内的时候,我的老大就对我们说,这是一件可以稳固我们团队地位的事情,拼死也要拿下这一战。大家都拿出了很坚定的信念,完成了这一战。内紧外松这个策略还挺好的,外部对你的预期相对低,然后内部拼命的做,最后的结果,往往比较容易超出大家的预期,我觉得这是一个很好的策略。
这次重构下来真的是收益颇多,真的非常感谢我的老大,非常的有智慧和方法论。
三、结语
上述其实也是讲了一个大概,由于时间有限,其中还有很多细节没有聊到,比如重构的过程中,同时有开发,这个时候如何保证开发的与重构的保持一致,以及要接手的项目重构发现,对这个项目熟悉的人比较少,该如何重构等问题。感兴趣的朋友,可以留言进一步讨论。觉得对你有帮助的朋友,记得一键三连哦,感谢感谢。
版权归原作者 Joeliawu 所有, 如有侵权,请联系我们删除。