谈谈代码重构

3,846 阅读5分钟

好久没写文章了,最近太忙了,诈个尸,恰好最近在代码重构,简单谈谈什么时候重构、重构的原则以及怎么实施去重构。

什么时候进行重构?

任何时间都可以进行重构,前提是你有足够的时间以及精力去做这件事情,大部分公司重构代码是不会计入KPI的,甚至重构的越多,出bug的概率就越大,背锅的可能就越大。因此,小规模的重构或者自己负责功能的重构,可以穿插在需求中进行;大规模重构因为耗费时间较长,出错概率较高,必须要得到上级的支持才能进行下去。大规模重构的需求来源一般都是因为目前技术架构已经不能满足快速的业务迭代,可维护性差,新人上手困难,出现bug几率增加,当代码已经到达这个程度的时候,就需要推进进行大规模重构了。

重构的原则

需要理清楚的是重构不是重写,更不是解决bug,引入新需求。很多新手在进行重构的时候,往往会在重构过程中去修改之前的固有逻辑,甚至增加一些自己的业务理解去“优化”现有的代码,这是大错特错的,因此重构的第一个原则是:“忠于原代码”,特别是在自己无法理解之前业务的下,尽量忠于原文,可以减少产生的新的bug,可测性增强。

重构的第二个原则:“逐步实施”。尽量不要一下子就推翻重建,应该从尽量底层去抽取共性,由点及面,分解目标,逐步实施;比如你要对当前代码做整体的MVP重估,这个时候你可以先把当前业务理清楚,分析核心业务,从最简单的业务入手,保留原有的结构,逐步兼容,然后慢慢把之前的代码精简掉甚至移除。

重构的第三个原则:“简洁逻辑而非减少代码”,重构最终的目标是需要符合软件工程中单一指责以及开闭原则的,代码行数的多少不是关键,怎么理清楚逻辑,让后续维护方便,入手学习成本低才是最关键的。很多人以“从XXX行到XX行”为重构的目标,行数的减少是衡量指标之一,但绝不是最重要的指标。比如RxJava的引入,可能会增加代码量,但是逻辑更清晰了,增加功能更容易了,这就是成功的重构。

重构的另外一个原则就是:“合适的才是最好的”,很多人重构代码就是炫技,一旦给他重构代码的机会,就如脱缰野马,引入大量自己并不熟悉的框架进行,觉得这是一个学习的好机会,一旦出现问题就无法解决。怎么就算合适了,在我看来,合适的架构一定是以下几个特征:

  • 学习成本低,新人入手容易,市场上资料多;
  • 不过度设计,但是又容易扩展,以后换成新架构也方便;
  • 不要过度结偶;

前面两点比较容易理解,第三点怎么理解呢?写代码久了,就会明白一个定律:“代码逻辑守恒定律”,就是无论你怎么设计架构,代码逻辑是不会减少的,一个地方逻辑减少了,就一定会在另一个地方逻辑增加。解偶就意味着,你把不属于这一块业务的逻辑转移到另外一个地方,过度解构要么是划分了很多个模块,要么就是把对应的业务放在了“看不到”的地方,当“看不到”多了以后,就会造成查找问题非常麻烦,比如过多的在Java使用注解或者编译时注解。过度解偶其实就是隐藏了不必要隐藏的逻辑,对调用者完全透明,问题的追踪就会在透明层被截断,从而导致问题的产生。

怎么实施重构

参与重构人数不宜过多,两三人为宜;功能不宜分散,至少每个人应该要重构一个业务功能模块或者功能点,这样可以更好减少沟通成本。

大规模重构,应该从下至上,先理清晰要达到的目标,先从底层逻辑开始重构,逐步到上层。比如在Android中对之前代码的重构,应该是先模块,后组件,然后逐渐到具体业务,这样就可以保证整个过程中重构的一致性。

在进行重构之前,需要对要达到的重构目标做一个评估,是要完全重构完,还是只需要对关键业务做梳理,亦或是需要整理出一个模版,然后分布实施。不同的目标对应不同的做法以及不同的工作量;在重构之前还需要需要对当前关键业务做梳理,理清楚周边支撑组件和必须要提前的工作量。

比如,某一次重构:

  • 目标:完成所有业务模块的MVP重构
  • 关键业务:打车、订单管理、地图
  • 效果
    • 模块抽取(module1/moduel2...)
    • 基础组件
      • 推送/IM
      • 网络
      • 支付
      • ...
    • 规范
  • 预估时间 30天/1人

围绕关键业务设计,设计好了关键流程,重构就成功了一半。在重构中,还有一个比较基础问题就是:编码规范的问题;编码规范尽量使用工具去最规范。类似于sonar/lint等工具做到自动识别,自动提醒,不要浪费太多时间在上面。

总结

快下班了,先写到这里吧,有什么可以在评论中探讨。