实际上不矛盾。区别就是重构的方式应该从下往上还是从上往下。比如说我们现在大部分的重构都理解为从下往上来做。也就是感觉这个文件里头有坏代码的味道,然后就改这个文件,这样做是没有问题的。前提是这项工作的上下文比较单纯,无技术债务。
很多情况不是如此幸运的,比如现在有些人遇到的问题,就是发现上下文不是很清晰,这个代码为什么要这么写?为什么一个文件有1万行或者3万行,这个来龙去脉不是很清楚。
这个时候可能就需要从整个子模块来进行一个自上而下的分析。梳理出这个子模块的功能需求是怎样的,需要有多少个公共接口?内部公共接口的实现方式是不是应该像目前这样的?
一个文件能够写成1万行或者3万行,肯定是有一定历史原因的,绝大程度是由于全局把握的编程能力不够造成的。
像这种情况,如果从这个文件本身去做重构的话,难度非常之大,但是如果从上往下,从模块的整个设计角度来做重构的话,可能就容易一些。
对于这样的庞然大物,最好的办法就是分而治之。首先要确定系统的功能逻辑点,针对这些逻辑点,要编排好对应的检测点,也就是说等我们完成了重构以后,我们得确保我们的重构是没有问题的,这些检测点就是做这个的,我们可以理解成集成类的测试。
这些集成类的测试一定要确保可以在当前未重构之前的系统上正常运行。
有了这个设施以后,我们就可以开展我们的重构工作。重构的方法有很多,比如采用比较好的工具,函数和变量的命名改变,调用方式的改变等等。这些是在现有代码的基础上进行的重构。这里我们重点说一下重写的方式来实现重构。所谓重写呢,就是另外开辟一套代码底座。甚至可以选用不同的编程语言。
这种情况下重构首先要重用已有的业务逻辑,实现针对业务逻辑集成测试100%的通过率。
具体不管采用哪种方式都要一个模块一个模块的进行推进。验证完成一个是一个,千万不能急于求成,试图一次性的把某些问题搞定。如果出现很多次失败,有可能会消磨掉你的自信心。所以一定要一点一点的往前推进,始终是在进步当中。采用了这种方式以后,不管当前的系统有多么的庞大,你只要坚持做下去,就一定能够把重构工作彻底完成。
这个时候需要做的具体步骤可以参考如下:
1. 根据功能需求定义公共接口。
2. 根据公共接口写出测试案例代码。
3. 这个时候可以按照测试驱动开发的理念去填充代码。
4. 代码可以从现有的代码中抽取出来。
5. 在抽取的过程中进行整理重构。
这样,这个子模块完成以后,就可以尝试去替代现有的子模块,看看能不能在整个系统中安全的运行。
对于整个系统来说,我们又可以分成很多个子模块。然后又可以对各个子模块各个击破,最终完成对整个系统的重构。
如果一开始对整个系统进行重构的话,也是可以从自上而下的角度来看的。
比如说开始的时候先把所有的子模块看成一些占位符,假定他们已经完成他们的接口了。那对于整个系统来说,它本身就是一个子模块,属于提纲挈领的那个模块。
这个过程,从字面意义上可以理解成重写,实际上,它也是一个重构的过程,因为我们肯定会重用这个系统本身的一些现有代码和现有的逻辑。
上面我们是假定系统在已经完成的情况下进行的重构,其实重构可以贯穿于软件开发的始终。软件开发的首要目标是实现业务逻辑,能够解决客户的问题。这个目标实现以后,我们就要追求代码的干净度,复杂度能够降到最小,当前的技术能够用到最先进。
所以只要有机会,我们都应该对代码和设计进行重构。
质量质量直接关系到客户是否对我们的产品满意。那我们应该如何保证软件开发的质量呢?
要遵循整个开发团队的共识才能保证质量。共识是一个可大可小的术语,大到理想、哲学、人生观;小到软件设计原则,设计模式,代码风格。如果是打造一个团队那就是长期的目标,共识一定要从大的方向上入手。如果仅仅为了开发一个项目,共识可以从具体的细节着手。
软件质量的保证,需要整个团队形成共识,大家都遵循这个共识。这个共识体现在开发原则,设计模式和代码上,具体表现在架构代码和模板代码上,在项目最初的开发阶段,开发速度一定要慢,就是为了经过反复的推敲夯实,把代码的共识部分建立起来。
风格上的目标是,不管这个团队有多少个人,写出来的代码,就像一个人的代码一样,风格是一致的。
代码的质量也体现在复杂度上。复杂度的目标是,在目前的技术条件下,当前的代码的复杂度应该为最低。