重构不等于重写
上周公司内部开发部交流会上,一些同事就自己的工作情况提到了一些关于重构的内容,大家就重构内容进行了简单的讨论,一些同事提到了重构的原因,实现的功能不好、效率较差等。在现实工作中,“重构”更多被用来成为弥补缺陷、增加功能、修改设计等工作,而很多人潜意识里也认为重构就是修改、重写代码,而这往往曲解了重构的本意。重构是一个过程,是建立在不违背外在行为的前提下,对代码进行修改,改进程序的内部结构。重构不等于重新设计,软件工程里一定要先进行设计,再进行编码,而如果你在之后对设计进行了改变,那只能说明当初的设计不够合理或不够完善。
为什么要重构?列下本人认为可能会导致重构的原因
- 代码重复,首当其冲。个人认为,重复是一大忌,而增大软件的复用程度也是程序设计的主要目标。如两个函数用到了同样的表达式,那么就应该考虑抽取一个公共的表达式函数,如果不同的类用了出现了重复代码,那么就应该考虑提取公共的类。
- 不符合代码规范。代码规范应该在前期编码时尽量避免,但谁也不能保证自己的代码没有任何规范上的问题,而事实上,因为不符合编码规范而进行重构的占相当一部分,如子程序过长,嵌套过深,命名较差,使用全局变量,没有良好地使用注释,函数参数过多等。
- 类的内聚性太差,类之间的耦合性过大。如果一个单一的class做了许多彼此无关的事,那么就不可避免的出现太多的instance常量,代码重复也会接踵而至。通常情况下,这些类应该被拆分提取为多个类,每个类负责一且内在的任务。
- 类的接口定义不够完善,不够一致。接口即服务,如果一个接口没有定义得很好的话,往往体现了业务逻辑关系没有抽象好,导致未能提供层次一致的抽象。有些程序员常常一怒之下将类大改,这常常导致违背了最初的契约,此时类的接口会变得异常可怕。而类的耦合过大往往导致修改一个类时,要改相应的很多类,这时类的代码就当被重新组织。代码的重用很重要,工作量的重用也很重要,应该尽量避免同样的工作进行多次。
- 代码的安全性和健壮性较差。如数据成员被置为公用,没有提供数据库的安全访问方式,没有实例化对象就调用对像的属性等,这些不安全的代码常常是程序隐患,代码安全性的问题追踪往往是较为困难的,特别是在软件发布之后,羽开发之初应该尽量避免,个人认为一个较好的办法就是加强开发者测试。
- 代码实现晦涩,不易维护。代码是写给人看的,而不是写给机器看的。不要为拙劣的代码写注释编文档,应该重写代码。
- case或switch语句,需要相同的修改,对case语句的修改常常导致对类似的一组case语句做出相同的修改,此时应该考虑是否用继承更为妥当。
总之,应该明确一个观点,持续重构,避免重写,重新设计和重写不能成为重构的代言词。
从项目管理方面来看,导致需要重构或重写的原因:
- 越来越多的特性。它会导致复杂度的提升。
- 捷径和权宜之道。为了支持诸如”我们在八月份需要这个NB的搜索,没二话”之类的特性
- 开发者轮换。新的开发者根本不知道架构之后的所有起决定性作用的决定和主意。知识不可避免地随着人员的轮换而流失。
- 开发团队的扩大。更多的人导致更少的交流,更少的交流产生糟糕的决定。