程序员需知的五种静态代码审查

来源:互联网 发布:c语言 mobi 编辑:程序博客网 时间:2024/05/29 09:16

http://school.itzcn.com

 

静态分析的概念已经提出多年,而在过去的几年里利用该工具评估和诊断代码的技术已日趋成熟。几乎每种语言都存在相应的软件审查工具。这些审查可以在多个领,如数组循环,编码风格,设计,复制代码,命名风格,性能等领域中隔离出不良代码。而在每一个层级中又存在另一套完整的审查可供程序员使用。

  这里要提醒大家,程序员可能会因审查报告过多漏洞而感到厌烦。笔者曾经看到过一个有20万行的应用程序,用现在的标准来衡量,这当然不算多,此外还运行了200+审查。该报告列出了35万个需要修复的违规之处,这样以来的确是有些麻烦。

  要想成功使用审查,关键是要限定审查套组的量。这个量视情况而定,程序员应该把握好这个量,才能事半功倍。

  我们通常会推荐程序员和其团队从小的有限审查开始,先修复各种常见问题。

  审查最令人激动的一点是它可以为我们提供代码信息以及代码的构成。仅因为报告指出某一行出现异常,这并不意味着它就是真正的问题所在。一个好的工具应该能够将所报告的问题做上已验证的标记;可以在注释中标明,这样审查工具就明白该区域已经被查看过了。

  那么什么时候可以使用审查呢?建议每晚或进行整合构建的时候都可以运行审查以便保证程序的运行,尤其是当代码的编写不够严格或刚刚编写完不久的情况下。运行已有代码中的Software Archeology时至少应该运行一次代码,而重构进程的时候则要一直运行审查。

  本文介绍的五个审查工具分别是Numerical Literal in Code,String Literal,God Method,Shotgun Surgery和Duplicate Code。

  Numerical Literal in Code

  这是最简单的重构方法之一。我们已经写出这样的代码:

  

     double salaryCalc(double salary){

  return salary*1.34564333721

  }

      C++

  两个月后,我们要更新salaryCalc方法,而客户查看代码的时候则遇到了困难。很可能他们不记得方法最开始的写法了,所以不明白1.34564333721代表着什么。最好是用字符常量来代替数字。这样就赋予了数字有意义的名称,如下所示:

         double salaryCalc(double salary){

  Return salary* BONUS

  }

  Static final double BONUS = 1.34564333721

  C++

  当程序员查看现在这个代码时,他们至少明白1.34564333721代表的是什么。如果你要重构,单元测试不应该发生改变,而重构完成后结果应该还一样。

  String Literal

  我们都知道,时间紧迫的时候,我们可能要改变代码,并使其能尽快投入运营。String Literal就派上用场了。该审查特别适用于要将软件国际化的任务。需要经常运行该审查。单元测试不应发生改变,结果也要保持一致。

这个不正确:

  public const helloWorldMessage: String = ‘Hello World!’;

  Delphi

  这个才正确:

  Public const helloWorld Message: String =

  resourceManager.GetString(‘msg.helloworld’);

  Delphi

  这个方法将会对应用程序外能够被改变的资源包中的helloWorldMessage字符串进行检索,并在不重新编译的情况下进行更正。

  God Method

  God ‘X’审查,‘X’相当于Method,Class。该审查不仅仅是查看代码,然后指出不足。

  对这一类审查的概括可总结为god Method;简而言之,我们拥有一个类,这个类包含了50个方法,但是只有一个方法恰好能完成所有工作。那么这个方法就要被标记为god Method。

  顺便说一下,大多数god ‘X’情况都不是这样开始的。在god Methods的情况中,它们通常会以常规的简单方法开始,但是随着时间的推移,功能越来越多,方法要负责的方面也越来越多,因此慢慢成为了功能齐全的God Method。

  那么什么样的计算用于指明哪一种方法比其他方法的功能更多呢?通常计算所涉及三种主要审查和一套代码都是用于确定其状态。这三种审查包括Long Methods,Long Parameters和Switch语句。四种基本代码包括:程序编码行,参数量,本地变量数以及分支指令的最大数。

  把这些数放在一起就可以看到计算是如何运行的。Long Methods通常意味着执行一个以上的操作,Long Parameters较难理解,Switch语句代表代码中的不同路径。通过在程序编码行加入要与其他方法进行对比的方法,然后验证参数量,本地变量数以及分支指令的最大数,它就可以计算出到底哪个才是Gog Method。

  当我们分离出God Method后,又该怎么办呢?这时候会产生许多重构器,如Extract Method,Introduce Parameter Object等。目的是要确定该方法按照预计的方式在执行。

  Shotgun Surgery

  该审查是笔者最喜欢的审查之一,不仅是因为它的名字很酷,还因为它可以帮助程序员节约大量时间。和god ‘X’审查一样,该方法也使用代码来计算其结果。

  大家有没有尝试过用需要修改的一行代码来隔离一个方法呢?如果使用shotgun surgery审查,将节约很多时间。因为该审查会查看代码中依赖某方法的位置。这意味着你将知道某一行的更改将改变整个代码基础,你最好是在更改代码行之前仔细考虑清楚。

  要用来帮助shotgun surgery方法进行计算的另外两个方法分别是Changing Methods和Changing Classes。Changing 方法审查是紧密相关的方法数,Changing 类是更改方法的时候受到影响的类。因此可以将shotgun surgery审查视为依赖于小型方法的检查。

  所以,如果你所拥有的方法中包含了shotgun surgery,该怎么办?很简单,看清楚代码,找到下属的小型方法,然后查看预定的更改要对系统做些什么操作。

Duplicate Code

  曾几何时,笔者认为 复制/粘贴 功能应该从编辑器中清楚。我们使用这一功能的频率令人吃惊。这种方法导致我们复制了大量不良代码。

  而复制不良代码所带来的最严重问题就是维护了。使用这个审查我们要能够寻找到那些只做过稍微修改的代码。很多工具在审查返回信息前会说明有十行,或更多行代码需要被复制。推荐大家将复制数量的设置降到三或四行。

  一旦程序员隔离出复制代码,那么一组标准的重构方法就可以发挥其作用,通常Extract Method或Pull Up Field可以做到这一点。

  如下所示,一个这样的If语句:

         if (int x=0; x< 100; x++{

  //other statements

  someValue = 10;

  } else {

  //other statements

  someValue = 10;

  }

  Java

  可以写成这样:

        if (int x=0; x < 100; x++{

  //other statements

  } else {

  //other statements

  }

  someValue = 10;

  Java

  这一简化的示例很好地展示了其效果;someValue每次都会改变成10。

  现在有很多的审查可供选择。记住当你要开始审查的时候,先选择小一点的和那些能快速给出反馈信息的。

  审查是程序员容易忽视的工具。花些时间找到一些适合自己的审查,将会节省很多开发时间。

原创粉丝点击