前言
作为拥有几年工作经验的程序员,都会对糟糕的代码(Bad Code)感到不满。如何将烂代码变成好代码?本文将由浅入深、一步步带你理解重构的奥秘,让你对重构有个基本的了解。
任何一个有几年工作经验的程序员都经历过这样的场景:回顾早期写的代码,会陷入深深的怀疑,这么烂的代码是我写的吗?相比起刚入行时候的你,这几年不管是自己发奋学习,如阅读《编程模式》、《重构:改善现有代码的设计》等经典著作,还是公司大神对你耳提面命,你对程序架构、编码规范的认识都有了很大的提升。还有一种情况是做项目的时候,或多或少存在赶工期的问题,很可能为了能在 deadline 之前交付,某个问题的解决方案并不够优雅。
以每一个有责任心(代码洁癖)的程序员都会去考虑重构的问题,重构代码有很多好处,正如作者在文章中提到的:后期修正 bug 更加容易、提高程序的可读性、改进程序原有设计,更重要的是当你在小组讨论会上,向同事展示代码时不会觉得丢人。以上这些好处是彼此联系的,比如当你接手一个遗留工程,前开发人员早已不知去向,不管是要增加功能还是修正 bug,你都需要读懂代码,这就需要提高程序的可读性,你能依靠的除了你堪比福尔摩斯的推理能力,就只有重构这把利器了。
虽然重构有这么多好处,为什么当我们准备开始的时候,却会反复纠结?作者大致提到以下原因:
- **担心破坏已有代码。**这种情况在核心业务系统尤为普遍,比如电商平台,企业的 ERP 平台等,系统需要 7*24 运行,你的一个修改可能导致严重的资损。作为普通人的我们,自然会抱着多一事不如少一事的心理,毕竟出了问题,会吃不了兜着走。
- **不能立即看到产出。**在每日的 stand-up 会议中,当研发经理问我,你今天干什么了,我说重构代码,如果连续三天都是这个答案,估计研发经理就要发飙了。
- **没有时间去做。**面对繁重的研发任务和日益逼近的 deadline,重构,真的不是一场说走就走的旅行。
说了这么多,读者朋友可能会有一个想法,是否有一些方法,能让我享受重构的好处,又能避免上面提到的风险。
幸运的是还真有!下面我将从最简单、基本不会破坏已有代码、花费很少时间的重构方法入手,逐步深入,让大家对重构有一个基本了解,在对方法的介绍中,我将按照调研情况,选取用户掌握最多的编程语言 Java,以及该语言使用最多的 IDE 环境 Eclipse,进行举例。
重构入门
为了消除恐惧,让我们从最简单的重构方法入手。
1. 格式化代码
当你发现代码缩进层次不齐,代码块中缺少{}等问题时,就需要考虑代码格式化了。现在的 IDE 工具已经对格式化提供了很好的支持,以 eclipse 为例,选中要格式化的代码,点击菜单项就能完成代码格式化。
此外很多源代码管理网站,也提供了格式化工具。在团队开发中,为了保证开发代码样式统一,需要建立编码规范。我们并不需要重头建立编码规范,可以在大厂的编码规范基础上进行定制,比如在 Java 领域可采用阿里、华为、Google Java Style Guide 等编码规范。该编码规范可以与 IDE 进行结合,如在 eclipse 中,打开 Window->Preferences->Java->Code Style 导入编码规范。
重要的是,不管选择何种规范,要坚持下去,并让每个团队成员都用起来。
2. 注释
在代码开发中,好的注释可以提高程序的可读性,坏的注释可能会画蛇添足,甚至起反作用。作者提到好的注释要做到和代码相关、及时更新。很多时候,代码刚开始编写时,注释和代码是一致,后期因为间隔时间过长或其他人接手修改代码,没有对注释及时修改,就会造成注释和代码渐行渐远。
尽量减少不必要的注释。如很多函数或者类,如果设计架构清晰,通过命名就能知道他们做什么,注释不是必须的。还有一种情况是暂时不用的代码,很多人会觉得以后会用到,会加个注释,作者给出的建议是删掉它,如果你将来真的用到了,可以到 git(一种代码管理工具)的历史记录中查找。
对于逻辑混乱的代码,如在循环中随意使用 break,复杂的 if 语句嵌套等,你要做的是理清逻辑,重构代码,而不是让注释替你补锅。正如《重构》中提到的'当你感觉需要撰写注释,请先尝试重构,试着让所有注释都变得多余。'
3. 废弃的代码
随着系统版本的不断迭代,有一些函数或类不再使用后,我们应该将它及时删除,否则随着时间流逝,会造成代码库臃肿,程序可读性变差。而且如果还发生人员的变动,慢慢会成为谁也不敢动的代码,因为都不知道有啥用和在哪用到。
多先进的 IDE 工具都对查找代码的调用提供了支持,以 eclipse 为例,查找函数是否被调用,可以使用调用层次图功能,或者直接使用高级搜索功能。在调用层次图(Call Hierarchy)中可以看到 getInstance() 函数被什么地方调用。
如果使用类似于 spring 的自动装配功能,在 xml 中定义了调用关系,可以使用高级搜索功能查看 xml 或 properties 文件中定义的同名函数进行筛选。
4. 变量命名
就像我们人一样,一个好名字对变量、常量、函数和类都很重要,一个好的名字会让其他开发人员很容易明白其功能是什么。以下是命名的一些注意事项:
- 类和文件名使用名词,但这个名词要有意义,比如 Data、Information 就意义不明显,不是好名字。
- 函数使用动词或短语命名,比如 isReady hasName。


