前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Apache Hadoop:通过重构降低技术债务

Apache Hadoop:通过重构降低技术债务

作者头像
用户1090667
发布2018-05-31 16:34:38
7010
发布2018-05-31 16:34:38

如果没有将实际行动纳入代码来控制和解决技术债务的话,那么技术债务将一文不值。为了阐述这种能自动修正代码缺陷的能力,而这些缺陷恰恰又是增加这些意外债务的元凶,我们对Hadoop项目的两个子项目进行了代码重构:Hadoop Common 和Hadoop Mapreduce。为此要感谢Scertify,我们能够在2分钟内纠正25k个缺陷。换句话说,技术债务中的14%已被勾销而不需要任何人力。

技术债务是没有价值的,如果没有将实际行动纳入代码,以控制和解决它。为了说明自动纠正代码缺陷的能力,增加了这种意外债务,我们对Hadoop项目的两个子项目进行了代码重构:Hadoop Common和Hadoop Mapreduce。感谢Scertify,我们能够在2分钟内纠正25K个缺陷。换句话说,技术债务的14%已被注销,而无需任何人力。

初步分析

参考维基百科,Apache Hadoop是“支持数据密集型分布式应用的开源软件框架”。该框架包含几个项目,Common和Mapreduce是两个重要的项目,分别具有12万和16.2万行代码(不包含空白行和注释)。我们使用的版本是最新的开发版本:3.0.0-SNAPSHOT。我们在这些项目上运行了我们的Sonar的开源插件Scertify Refactoring Assessment,以便全面了解他们的技术债务。

根据维基百科,Apache Hadoop是“支持数据密集型分布式应用的开源软件框架”。该框架包含几个项目,Common和Mapreduce是两个重要的项目,分别具有120K和162K行代码(空白行和注释除外)。我们使用的版本是最后一个开发版本:3.0.0-SNAPSHOT。我们针对这些项目运行了Sonrt的开源插件Scertify Refactoring Assessment,以便全面了解他们的技术债务。

技术债务定义为纠正所有检测到的缺陷所需的时间。正如您在屏幕截图中所见,Common有70天的技术债务,Mapreduce有66天。Scertify重构评估还计算了自动修正技术债务的潜力:债务抵消。他们都有自动重构的潜力,分别为38天和36天。因此,下一步是使用Scertify来执行这个自动重构。顺便提一句,如果您想用您自己的源代码来尝试它,Scertify的安装和用户指南可以在这里找到。

技术债务定义为纠正所有检测到的缺陷所需的时间。正如您在下面的屏幕截图中看到的,Common有70天的技术债务和66天的Mapreduce。Scertify重构评估还计算了自动修正技术债务的潜力:债务抵消。他们都有自动重构的潜力,分别为38天和36天。所以,下一步是使用Scertify 来执行这个自动重构。顺便说一句,如果你想用你自己的源代码来尝试它,Scertify安装和用户指南可以在这里找到

我们滚动了各种不同的错误并选择了8条规则来执行演示。

我们在各种错误中滚动,我们选择了8条规则来进行演示。

演示的重构规则

这里有我们在这个演示中使用的重构规则的展示。如您所见,一些规则需要参数才能有效

这里是我们在这个演示中使用的重构规则的演示。正如你所看到的,一些规则需要参数才能有效。关于伐木的规则就是这种情况。这些项目中使用的日志框架是Apache Common logging,所以我们配置了规则来使用这个框架。

AvoidPrintStackTrace

此规则在找到捕获表达式并将其堆栈跟踪打印到标准错误输出的代码时会报告违规情况。应该使用日志框架来改善应用程序的可维护性。重构通过调用日志框架来替代调用打印堆栈跟踪。该规则还可以在类中声明记录器并进行所需的导入。以下是GenericWritable类中原始代码和重构代码的示例。

原始代码:

代码语言:javascript
复制
catch (Exception e) {
      e.printStackTrace();
      throw new IOException("Cannot initialize the class: " + clazz);
}

重构代码:

代码语言:javascript
复制
catch (final Exception e) {
      LOG.error(e.getMessage(), e);
      throw new IOException("Cannot initialize the class: " + clazz);
}

在这种情况下,LOG没有被声明,所以它被添加到类中并导入:

代码语言:javascript
复制
private static final Log LOG = LogFactory.getLog(GenericWritable.class);

InefficientConstructorCall

调用包装类型的构造函数(如Integer)来转换基本类型是一种不好的做法。它比调用静态方法valueOf效率低。

PositionLiteralsFirstInComparisonsRefactor

这一规则检查文字在比较中处于第一位。重构反转了文字和变量。这确保了代码不会因变量为空指针而崩溃。

AddEmptyStringToConvert

使用空字符串连接将基元类型转换为字符串是一种不好的做法。首先,它使代码不易读。在大多数情况下,它的效率也较低(字符串连接稍微好一些的唯一情况是该原语是最终的)。以下是从MD5MD5CRC32FileChecksum类获取的示例。 原始代码:

代码语言:javascript
复制
xml.attribute("bytesPerCRC", "" + that.bytesPerCRC);

重构代码:

代码语言:javascript
复制
xml.attribute("bytesPerCRC", String.valueOf(that.bytesPerCRC));

GuardDebugLogging

在调试日志中执行串联字符串时,应在调用之前检查是否启用了调试。否则,字符串连接将始终完成。重构在调试调用之前添加一个警戒。在这种情况下,它被配置为使用isDebugEnabled()方法,因为我们使用Apache的日志。下面是从类ActiveStandByElector中取得的重构代码的一个例子:

代码语言:javascript
复制
if(LOG.isDebugEnabled()){
        LOG.debug("StatNode result: " + rc + " for path: " + path + " connectionState: " + zkConnectionState + " for " + this);
}

IfElseStmtsMustUseBraces

此规则会查找不使用大括号的语句。重构添加了需要的大括号。

UseCollectionIsEmpty

此规则查找Collection的size方法用于检查集合是否为空。而不是使用size(),最好使用isEmpty()使代码更易于阅读。通过调用isEmpty()来重构大小和0之间的比较。

LocalVariableCouldBeFinal

该方法标记可以声明为最终的局部变量,而不是。使用final关键字是未来代码阅读器的有用信息。重构添加了“最终”关键字。这不是一个关键规则,但由于它有大量违规,因此通过自动重构快速消除它们是有用的。

重构结果

所以我们在两个项目上运行Scertify来检测和重构这些规则。在每个项目上,大约需要1分钟来完成整个过程。Scertify生成一个html报告,其中包含有关检测到并更正错误的信息。以下是两个项目中纠正的所有错误的总结。许多小事情得到纠正,但也是更重要的。总体而言,纠正25392个缺陷需要2分钟的时间。不是很糟糕吗?这些缺陷包括轻微违规和更严重的可维护性,性能或稳健性方面的违规行为。

正如您在下面的屏幕截图中所看到的那样,在纠正这些缺陷后,每个项目的技术债务已经减少了10天。总的来说,这是20天的技术债务已被注销。

最后但并非最不重要的一点是,Hadoop包含许多单元测试,当然我们确信它们在重构后仍然成功。总之,得益于Scertify的重构功能,我们能够在几分钟内有效纠正25K缺陷。我们很高兴将重构代码提供给社区,您可以在下面下载它。我们将继续对开源应用程序进行这种重构,所以如果您有一个可以利用重构的开源项目的想法,请告诉我们!

下载源文件

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初步分析
  • 演示的重构规则
    • AvoidPrintStackTrace
      • InefficientConstructorCall
        • PositionLiteralsFirstInComparisonsRefactor
          • AddEmptyStringToConvert
            • GuardDebugLogging
              • IfElseStmtsMustUseBraces
                • UseCollectionIsEmpty
                  • LocalVariableCouldBeFinal
                  • 重构结果
                  • 下载源文件
                  相关产品与服务
                  大数据
                  全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档