降低代码重构的风险

标签: 代码重构 风险 | 发表时间:2012-11-15 15:15 | 作者:
出处:http://pipes.yahoo.com/pipes/pipe.info?_id=10560380f804c7341f042a2b8a03e117

重构是每一个开发人员都要面对的功课,Martin Fowler将其定义为“在不改变软件外部行为的前提下,对其内部结构进行改变,使之更容易理解并便于修改”。技术专家Paul在 博客中讨论了重构的风险,并提出了降低风险的措施。

Paul在文中指出:

重构代码是危险的,代码的变化会导致测试的压力很大。除非有必要的理由,否则不要轻易重构。我指的重构并不是说把while循环改成for循环,或者把StringBuffer改成StringBuilder,而是指比较大的改动,比如重新方法、函数或者整个类或者包。

错误的重构时机包括:

  • 代码逻辑对你来说过于复杂,而且没有时间去分析它。
  • 你没有理解为何之前的开发人员是这样编写代码的。
  • 你参与的系统是关键系统,而且时间紧。
  • 你对团队、应用或者编程语言是新手。

正确的重构时机包括:

  • 现有的代码比预期的要复杂,而且你已经分析过它。
  • 你所做的改动比现有代码逻辑更加清晰。
  • 你有时间、人力和财力来增加完整的项目回归测试。
  • 现有代码过时了而且效率低下,比如孤立的或者质量差的代码。
  • 你和同事讨论过重构代码的好处和风险,并且达成一致。

如何减低重构风险呢?Paul认为可以从以下几点入手:

  • 利用自动化的回归测试来快速验证你的代码更改,这非常重要,如果你还没有准备好自动化回归测试,那么请在重构之前先搭建好测试环境。
  • 努力把代码的重构安排在较小的开发周期内。
  • 尽量把更改独立化,方便查找问题。
  • 确保测试计划包含了所有的回归、功能、负载、性能和用户验收测试。
  • 在开始重构之前,花时间弄清楚复杂的代码逻辑。
  • 在需要时利用设计模式,不要为了用而用,必须要充分的理由。

无独有偶,技术专家McConnell在“代码大全”中也提到了安全重构的措施。

保存初始代码——在开始重构之前,要保证你还能回到代码的初始状态。用版本控制系统保存一个初始版本,或者把最初正确的文件复制到备份目录中去。

重构的步伐请小一些——这样才能理解所做修改对程序的全部影响。

同一时间只做一项重构——除非是对付那些最为简单的重构,否则请在同一时间只做一项重构,在进入下一项重构之前,对代码重新编译并测试。

把要做的事情一条条列出来——伪代码编程过程的自然延伸就是列出一份重构列表,然后你应该按照这份列表从A点一步步走到B点。写一份重构列表能够让你在修改时保持思路连贯。

多使用检查点——在重构的时候,很容易出现代码没有按照设想正常运行的情况。除了保存初始代码外,在重构中还应在多个地方设置检查点,这样一来,即使你编码时钻进了死胡同,仍然可以让程序回到正常工作的状态。

利用编译器警告信息——要让一些小错误错过编译器的目光很容易。你最好把编译器的警告级别设置为尽可能苛刻,一旦输入中有这些小错误,编译器就能立刻把它们找出来。

重新测试——应该把重新测试作为检查所修改代码工作的补充。当然,这点要取决于从一开始你是否就有一套优秀的测试用例。

增加测试用例——除了重新运行过去做过的那些测试,还应该增加新的单元测试来检验新引入的代码。如果重构使得一些测试用例已经过时,那么就删除这些用例。

根据重构风险级别来调整重构方法——有一些重构实施起来会比其他重构更为危险。而类似于“用具名常量替代神秘数值”一类的重构则机会不会出现什么问题。涉及到类、成员函数结构、数据路架构等改变,或者对布尔判断等进行修改的重构则极具风险。对于简单的重构而言,你只需要简化整个重构过程,然后简单的对代码重新测试,而不用一次去完成一个重构,也不用进行正式的检查工作。

不适合重构的情况包括:

不要把重构当做先写后改的代名词——重构最大的问题在于被滥用。程序员们有时会说自己是在重构,而实际上他们所完成的工作仅仅是对无法运行的代码修修补补,希望能够程序跑起来。重构的含义是在不影响程序行为的前提下改进可运行的代码。那些修补破烂代码的程序员们不是在重构,而是在拼凑代码。

避免用重构代替重写——有时,代码所需要的不是细微修改,而是直接一脚踢出门外,这样你就可以全部重新开始。如果发现自己处于大规模的重构之中,就应该问问自己是否应该把这部分代码推到重来,重新设计,重新开发。

Kent Beck认为,重构中面临 最大的挑战就是如何做到循序渐进,循序渐进指的是如何将工作分解为可控的步骤,并且每个步骤都易于管理。重构步伐过快会导致不稳定代码的出现。此外,想得越多,越是谨慎反而会严重减慢重构的步伐。

正如许多与我结对编程的伙伴都会告诉你的那样,我有一个非常不招人喜欢的习惯:在重构时总会说“不要再想啦”。我知道这并不是我真正要说的,因为我不可能去故意表达这个意思,但是直到现在,我才有机会可以给出一个更好的解释。

垂直重构是指调整方法或代码块在调用堆栈中的上下顺序,然而水平重构则指的是在类似于同级别的对象间所做的调整。依Kent所述,重构时应避免同时做上述两种调整。

当需要重构具有多重调用或是多重实现的对象时,就要额外小心,并且重新回到垂直和水平方法,将这两者操作分开进行,并且要时刻注意代码重构的深度。

Kent Beck认为比较好的一个办法就是使用索引卡(Index Cards):

在电脑旁放置索引卡会帮助我保持专注。当我在处理水平重构时突然意识到还可以做垂直重构时,我会迅速记在索引卡上,然后马上回到刚才正在进行的工作中。这种方法不仅可以使我在进行下一步工作前,有效地先将手头的工作结束,同时,又不会导致某些好点子被遗忘。方法之好用,整个过程感觉就像是在做冥想,技能感受到自己的呼吸,又不会被完全自我的意识所牵绊。

InfoQ的读者对代码重构有何见解?欢迎发表自己的看法!

崔康 热情的技术探索者,资深软件工程师,InfoQ编辑,从事企业级Web应用的相关工作,关注性能优化、Web技术、浏览器等领域。

您可能也会喜欢

相关 [代码重构 风险] 推荐:

降低代码重构的风险

- - InfoQ cn
重构是每一个开发人员都要面对的功课,Martin Fowler将其定义为“在不改变软件外部行为的前提下,对其内部结构进行改变,使之更容易理解并便于修改”. 技术专家Paul在 博客中讨论了重构的风险,并提出了降低风险的措施. 重构代码是危险的,代码的变化会导致测试的压力很大. 除非有必要的理由,否则不要轻易重构.

代码重构

- - ITeye博客
随着程序的演化,我们有必要重新思考早先的决策,并重写部分代码. 代码需要演化;它不是静态的事物. 重写、重做和重新架构代码合起来,称为重构.    当你遇到绊脚石  ---  代码不在合适,你注意到有两样东西其实应该合并或是其他任何对你来说是"错误"的东西  -------- . 如果代码具备以下特征,你都应该考虑重构代码:.

代码重构总结

- - 开源软件 - ITeye博客
重构:对软件内部结构的一种调整,目的是在不改变软件之可察行为前提下,提高其理解性,降低其修改成本. 创建一个新方法,命名以它做什么来命名,而不是怎么做来命名. 如果只是简单的委托,可以将方法内联. 被子类继承的方法不能内联. 如果一个临时变量只被简单的表达式赋值一次,就可以将它内联. 将这个临时变量申明为final.

代码重构方向原则指导

- - 外刊IT评论
提示:如果您在阅读器里点击订阅本站的文章链接时发现有一个中转页,这说明你的订阅地址有误,本站的订阅地址(RSS)是:. http://www.aqee.net/feed/,请及时纠正. 重构是一种对软件进行修改的行为,但它并不改变软件的功能特征,而是通过让软件程序更清晰,更简洁和更条理来改进软件的质量.

代码重构:HTML与语义化

- - 标点符
在前端开发过程中,很多人谈到“模块化”,很少人特别关注“语义化”,简单的说大多数人更关注功能的实现,而忽视了实现的细节. 所谓HTML语义化,就是尽可能的理解要表达的内容,选择适合的HTML标签,将内容转换成浏览器认识的语言,通过浏览器传达信息给用户. 目前很多的前端书籍取名就叫精通DIV+CSS,让人感觉DIV可以搞定一切,但是DIV标签仅代表一个块状标记,HTML的每个标签都有它特定的意义,而语义化就是让我们在适当的位置用适当的标签,以更好的让人和机器(机器可理解为浏览器可理解为搜索引擎)都一目了然.

创业风险面面观

- Vincent - FT中文网_英国《金融时报》(Financial Times)
这是每一个想创业的人必须回答的终极问题. 在你开始创业之前,请认真思考一下,自己是否真的具备创业的决心和迫切欲望. 因为在生活中,荣耀的代价向来不菲,而在这个特殊的竞技场上,对于大多数人而言,代价可能更为高昂. 毕竟,当你不惜一切代价投身事业之时,“一切代价”不只是说说而已——它很可能成为现实. 你不能简单地仅以自己的资金来衡量创业的风险.

单面煎蛋,拿风险换美味

- ZX - 谣言粉碎机 - 果壳网
流言: 单面煎鸡蛋无法彻底杀死蛋内的残留细菌,容易引起恶心、呕吐和腹泻等中毒现象. 除此之外,生蛋白还会阻碍身体吸引维生素H,如严重的话,会导致皮疹、皮肤炎、脱发等状况. 真相: 鸡蛋是一种比较容易受到细菌污染的食品. 如果母鸡完全健康,刚刚下的鸡蛋中倒也不会有过多细菌. 不过,这种理想情况毕竟不大可靠,通常的母鸡体内可能会有一些致病细菌.

Godaddy的域名注册风险分析

- 0M - 月光博客
  据南方都市报的报道,国内知名的电影资料库网站时光网被关的原因终于有了答案,时光网关闭据称与涉黄有关,万网的工作人员称,万网是接北京市通信管理局的通知,称时光网“传播色情、淫秽”,因而停止了对该域名的解析,该工作人员还说,该通知并没有明确恢复解析的期限,“如果想恢复,必须找北京市通信管理局或者工信部.

使用ifttt背后的巨大风险

- Jack - 月光博客
  ifttt,是一个新生的网络服务平台,通过不同其他平台的条件来决定是否执行下一条命令. ifttt基于任务的条件触发,类似编程语言,让用户可以根据他们设计的流程设计一些小程序,让网络服务能够对某些行为作出反应.   ifttt 是一项创造性的应用,但是我和我的朋友们必须重视其背后隐藏的风险. this 称为 trigger,而 that 称为 action.

单面煎蛋,拿风险换美味

- Pony - 牛博国际
      许多人喜欢吃只煎一面的蛋. 对他们来说,尚未完全凝固的鸡蛋白与“溏心”的蛋黄实在是美味. 但如此烹饪出的鸡蛋,对健康是有风险的. 流言: 单面煎鸡蛋无法彻底杀死蛋内的残留细菌,容易引起恶心、呕吐和腹泻等中毒现象. 除此之外,生蛋白还会阻碍身体吸引维生素H,如严重的话,会导致皮疹、皮肤炎、脱发等状况.