代码重构的作用和时机

2015-02-23 22:30金戈
现代计算机 2015年2期
关键词:代码重构债务

金戈

(广州赛宝认证中心,广州 510610)

代码重构的作用和时机

金戈

(广州赛宝认证中心,广州 510610)

软件的修改会不断地产生技术债务,而重构是偿还技术债务的有效方法。对代码重构的作用进行归纳,体现在改进软件设计,帮助理解代码、发现缺陷和提升效率等方面;并分析在添加新功能、修改错误和代码评审这三个重构的时机。

代码重构;软件;技术债务

0 引言

在面对不断变化的需求时,由于仓促实现某些功能特性而对代码库及其架构产生的破坏,就会产生一种技术债务,如果现在不解决,这些债务遗留下来就会阻碍未来开发。而且,技术债务有一个致命的特点,那就是会利滚利。如果开发者在一个类中欠下了技术债务,之后的程序又对这个类进行了扩展和修改,再后的程序对扩展后的程序又做出了更大的扩展,或者说后来的程序在一些功能的写法上参照了欠下债务的类,那么这个债务就会产生非常大的利息,甚至于超过了债务本身。用不了太多时间就会发现,这份技术债务已经无力偿还了。因此,在开发过程中首先尽量不要欠下技术债务,其次一旦迫不得已欠下了债务,就应该以最快的速度偿还,时间拖得越久,偿还债务的负担也就会越重。

而如何偿还技术债务的答案就是重构。重构就是对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。

设计人员都会面临这样的难题,要设计一个可以应对各种变化、扩展灵活的产品是非常困难的。大部分设计人员,尤其是交付型项目的设计人员,往往没有足够的时间去详细设计产品的每个细节,在后续开发中进行设计的调整在所难免。随着代码的不断修改,系统的整体结构会变得混乱,代码质量慢慢沉沦,从而欠下越来越多的技术债务,阻碍整个系统后期的改变和发展。

重构则是一个相反的过程,它的每一个步骤都很简单,开发者只需要把某个函数中的一段代码拉出来形成一个新的函数,或者把一些方法在继承体系内进行移动,甚至修改一些变量名称和注释就可以了。这样,每一次微小的修改积累起来就可以从本质上改善设计和代码的质量。

1 代码重构的作用

当项目为了完成快速交付时,往往没有很多精力关注在设计和代码的结构上,随着代码的增多,代码逐渐失去了自身的结构。这种结构的流失累积到一定程度的时候,对代码的理解就会变得越来越困难。

再加上项目的需求总是不断地变化,项目组需要不断地对现有的系统进行修改和完善。为了尽快实现这些变更,不可避免地要违反最初的设计。因此软件的结构就会出现混乱,容易导致项目bug越来越多,软件的维护越来越困难。

重构能够最大限度地避免以上这些现象的出现。当项目开发到一定程度后,对系统使用重构的方式,在不改变系统外部功能的情况下,对内部的结构进行重新的整理。不断完善系统的结构,使系统对需求的变更始终具有较强的适应能力。

通过重构,可以带来以下几方面的好处:

(1)可以改进软件的设计

人们在修改和维护代码时往往只考虑短期内的目的,或者没有完全理解软件的整体设计,这样程序就会逐渐失去原有的结构,也越来越难以通过阅读源代码来理解软件原来的设计。并且代码结构的流失是积累性的,越难看出代码所表示的设计意图,也就越难保护其中的设计。而重构就像是对代码的整理,让代码的各个部分处于合理的位置上,通过经常性的重构来帮助代码维持自己应该有的形态。

设计不良的程序常常会在不同的地方使用完全相同的语句来做同样的事,从而需要更多的代码来完成特定的功能。因此消除这些重复的代码成为了软件设计改进的一个重要方向。虽然简化代码并不会让系统运行得更高效,但却使未来可能的对程序的修改变得容易的多。

(2)使软件代码更容易理解

Martin Flower在《重构》中有一句经典的话:“任何一个傻瓜都能写出计算机可以理解的程序,只有写出人类容易理解的程序才是优秀的程序员。”

目前,大部分软件已经不再是通过一个人就可以完成的了,软件需要大量的人员来进行开发和维护。为了使代码容易被他人理解,开发团队需要遵照统一的编码规范,需要让代码写得更加简练和可读性更强。通过代码的重构,可以使代码更加简洁,使团队成员更容易理解软件的设计思路,也就更容易读懂代码。

(3)帮助发现隐含在代码中的缺陷

开发人员在进行重构的时候,需要对代码进行理解,搞清楚程序的结构。这时,就容易发现之前编写的代码中没有关注到的一些问题。通过重构,可以将这些问题找出来,加以纠正,使代码更加健壮、质量更高。

(4)重构有助于提高编码效率

重构没有改变功能,为什么会提高效率?正如之前所言,重构可以帮助改善设计,而良好的设计是快速交付的根本。如果设计出现问题,开发团队会发现需要花大量的时间在设计不足带来的修改,以及理解系统等方面的问题上。

重构可以帮助建立良好的设计,及时找出程序中的问题,使我们的软件向良性方向发展,从而减少我们花在理解和返工上的时间,帮助提升编码的效率。

在重构的这些作用里,和设计的关系应当显得尤为重要,它们之间是一种互补的关系。在传统观念里,设计是软件开发的关键环节,而编码只是机械式的低级劳动,设计就像画工程图纸而编码就像施工。但是,软件和机械、建筑有着很大差异,软件的可塑性更强,而且完全是思想的体现。因此就产生了另外的一种观点,认为重构可以取代预先的设计。这代表我们根本不必做任何设计,只需按最初的想法进行编码,让代码有效运作,然后再将它重构成型。事实上这种方法是可行的,在极限编程中也会倡导这种方法。

尽管只运用重构也能得到效果,但这并不是最有效的途径,极限编程的爱好者们也会预先使用诸如CRC卡等方法来检验各种不同的想法并得到可接受的解决方案,然后才开始编码并进行重构。这关键在于重构改变了预先设计的角色。如果没有重构,就必须保证设计完全正确无误,并且如果将来要对原始设计做任何修改,代价都会非常高昂。而如果选择了重构并且仍然预先进行设计,那么在设计时只需要得到一个足够合理的解决方案即可。在实现这个初始的解决方案的时候,开发者对问题的理解也会逐渐加深,从而可以通过重构不断地完善设计。如此一来,软件设计变得更加简化。原先在设计时会力求灵活的解决方案,考虑软件未来可能变化的方向,并让这个解决方案能够适应未来的变化,但是灵活的设计会带来更高的复杂性和设计成本,并且有些灵活性的设计也未必能派上用场,而项目团队也无法预测哪些灵活性未来不会用到。有了重构,虽然仍需要思考潜在的变化,但却不必预先实现所有的设计,而是只考虑建造当前可运行的最简方案,以及将这个最简方案重构成一个灵活的方案。

2 代码重构的时机

对于何时进行重构,只要团队觉得有必要,任何时候都可以开始。如果资源有限,至少可以在以下三个方面开展重构:

(1)增加新功能重构

在添加新功能时,为了帮助更好地理解需要修改的代码,开发团队可以对已有的代码进行重构。不论之前的代码是别人写的,还是自己写的,只要需要理解代码时就可以考虑重构,这样可以随着程序更新的进展而不断理清代码结构,也可以从中理解更多的东西。当然,除了帮助理解代码外,还有一个原因就是代码的设计无法帮助开发人员轻松添加新的特性。在理解了原有的设计后,可以考虑用某种新的方式来设计,从而使添加新的特性变得简单,如此就能用重构来弥补之前设计上的不足。重构是一个快速流畅的过程,一旦完成重构,新特性的添加就会更加快速和流畅。

(2)修改错误重构

在软件调试过程中,对代码进行重构,可以让代码更具可读性。在阅读代码并试图理解它的时候,可以通过重构来作为帮助,并且在理解和重构的过程中可以找出代码中的bug,因而当团队收到缺陷报告的时候,就是需要开始重构的信号,这说明代码还没有清晰到可以一眼看出缺陷。

(3)代码评审重构

很多公司都会做代码评审,因为这种活动可以改善开发情况,它有助于在开发团队中传播知识,也有助于让较有经验的开发人员把知识传递给比较欠缺经验的人,并帮助更多的人理解系统软件中的内容。

重构可以帮助评审别人的代码。开始重构前可以先阅读别人的代码,得到一定程度的理解,并提出一些建议。一旦想到一些好的解决方法,就可以通过重构来实现它们。开发团队可以通过自己动手来实现它们,也可以通过提醒别人来实现它们。重构还可以使代码评审工作得到更具体的结果。不仅获得建议,而且其中很多建议能够立刻实现。

(4)何时不该重构

当然,在以下情况出现时,开发团队不应考虑对代码进行重构:

现有代码太混乱,重构不如重写。当代码中缺陷非常多,根本无法工作时,应考虑对代码进行重写而不是重构。重构的一个前提是代码能够在大部分情况下正常运行。

如果现有研发活动已经接近尾声,需要尽快交付时,也应避免重构。因为这时项目可能已经没有时间进行重构了。

3 结语

通过代码重构,可以帮助开发团队理解之前的设计,帮助发现代码中的缺陷,从而提高开发效率,偿还技术上的债务。而由于资源和时间的限制,团队需要确定是否需要重构,以及重构的最佳时机。重构的时机可以是软件开发过程中觉得需要的任何时候,包括文中提及的三个方面等。

[1] Martin Fowler.重构:改善既有代码的设计[M].熊节译.北京:人民邮电出版社,2010,4

[2] Robert C.Martin,Micah Martin.敏捷软件开发:原则、模式与实践[M].邓辉,孙鸣译.北京:人民邮电出版社,2008,1

[3] 陈容华.软件代码重构的时机[J].科技资讯,2009(28)

Effect and Opportunity of Code Refactoring

JIN Ge
(CEPREI Certification Body,Guangzhou 510610)

Code refactoring is an effective method to repay technical debt,which caused by the modification to software.Sums up the effects of code refactoring,including improving software design,helping code understanding,defect discovery and increasing efficiency.Analyzes three opportunities for refactoring:while adding new functions,fixing defects,and code review.

Code Refactoring;Software;Technical Debt

1007-1423(2015)02-0051-04

10.3969/j.issn.1007-1423.2015.02.013

金戈(1986-),男,安徽合肥人,硕士,工程师,研究方向为质量过程改进、软件工程

4-11-25

2014-12-16

猜你喜欢
代码重构债务
视频压缩感知采样率自适应的帧间片匹配重构
长城叙事的重构
北方大陆 重构未来
创世代码
创世代码
创世代码
创世代码
家庭日常生活所负债务应当认定为夫妻共同债务
北京的重构与再造
万亿元债务如何化解