vlambda博客
学习文章列表

改善 Java 代码质量的工具与方法

我们可能见过上面的有关代码质量的图片,究竟如何衡量一段代码好坏?


代码质量是什么?为什么它很重要?


作家通过他的著作来讲述了一个清晰的、令人信服的故事。他们使用章节、标题和段落等工具来清晰地组织他们的思想,并轻松地引导读者。


开发者的工作与作家类似,只是使用不同术语如命名空间、类和方法。如果创作者不能有效地使用他们的工具,那么无论他们的作品是书还是代码,读者都很难读懂。


回到代码质量这个话题,好的代码都应该具备如下一系列理想特征:


  • 可靠:能够稳定工作,不会频繁崩溃。

  • 一致的代码风格:遵循该语言一致的代码风格和命名惯例。

  • 可维护:易于理解,可维护的代码应该易于扩展及添加新功能。

  • 完善的测试:具备良好测试的代码往往 bug 更少。

  • 高效:不应使用不必要的资源来执行所需的业务。

  • 安全:应防止SQL注入等编码漏洞。

  • 较低的技术债务:较低的技术债务使团队能够快速前行和开发新功能,而不会被低质量和不可维护的代码拖累。


具备的上述特征越多,代码的质量就越高。根据项目及客户的具体情况,其中一些特性可能不是代码必需的。


当面临交付期限时,编写高质量的代码非常具有挑战,但如果你考虑到代码的长期可维护性,这一点很重要。同时,高质量的代码也会帮助团队长期保持一致的交付速度。


根据我的经验,下面是一些在我的项目中对改进和维护高质量代码非常有效的总结。


使用静态代码分析器提高代码质量


编译器可以捕捉和防止语法问题,但它们无法检测到类似情况:


  • 代码结构不一致

  • 社区已经成型的经验

  • 代码复杂性


静态代码分析是一种在代码运行前对其进行检查的技术。有一些工具可以进行静态分析,它的工作原理是根据多种编码规则分析代码,来发现一些违规行为。这些工具可以集成到构建工具中,如 gradle、maven 等,并让有问题的代码构建失败。


以下是一些可以整合到项目中的工具。



Checkstyle


Checkstyle (1) 是开发中用于检查 Java 源代码是否符合编码规则的静态代码分析工具。Checkstyle 进行的检查限于代码的表现形式,这些检查并不能确认代码的正确性和完整性。


  1. https://checkstyle.sourceforge.io/


使用 Checkstyle 可以确保开发团队遵循一致的编码风格,使其更容易阅读和理解。


下面是一些可以使用 checkstyle 进行的检查。


  • 属性和方法的命名惯例

  • 函数参数的数量

  • 代码每行最大宽度

  • 强制性的文件头描述,如版权

  • import 和范围修饰符

  • 字符之间的空格

  • Class 构建函数的约定

  • 多重代码复杂度测量


PMD


PMD(Programming Mistake Detector,编程错误检测器)(1) 是一个静态代码分析器,它可以报告在应用程序代码中发现的问题。


  1. https://pmd.github.io/


PMD 可以帮助检测代码中的问题,这些问题可能会在代码交付生产环境时引起问题。


  • 可能的 bug: 空的 try/catch/finally/switch 块,吞掉原来异常并抛出一个新的异常。

  • 死代码:未使用的局部变量、参数和私有方法。

  • 空的 if/while 语句

  • 过于复杂的表达式: 不必要的 if 语句,for 循环可以是 while 循环。

  • 次优代码:浪费的 String/StringBuffer 的使用

  • 高循环复杂度的类

  • 错误的 BigDecimal 用法



CPD(复制/粘贴检测器)


CPD (1),顾名思义,是一个基于拷贝的检测器,即使对于大型代码库来说也是非常高效的。它使用 Karp-Rabin (2) 字符串匹配算法编写。


  1. https://pmd.sourceforge.io/pmd-4.2.5/cpd.html

  2. https://xlinux.nist.gov/dads/HTML/karpRabin.html


它可以被配置为检测大于确定数量的标记的重复。复制/粘贴代码是不可取的,因为它使代码难以维护,并可能在对其中一个地方做了一些改变,而忘记在其他地方也存在相同的代码的情况下导致 bug。


衡量代码质量


免责声明:当一项措施成为目标时,它就不再是一项好措施。(1) 


  1. https://en.wikipedia.org/wiki/Goodhart%27s_law


代码覆盖率指标


代码覆盖率是一个指标,可以用来获得一些关于代码质量的信心。说了这么多,选择哪些测试来衡量覆盖率时要小心。并不是所有测试金字塔的测试都是一样的,像 JaCoCo 这样的工具可以用来计算代码覆盖率。


在看代码覆盖率的指标时,只应该考虑单元测试,因为单元测试是为了测试代码是否完成了开发者想要做的事情,执行这些测试是最快的验证方法。


衡量集成测试的代码覆盖率可能是有价值的,但它应该被视为单独的结果,而不应该与单元测试报告合并。记住集成测试是为了确保所有的组件一起工作。使用集成测试来提高代码覆盖率,就像使用大锤来敲开一个螺母一样。


毒性图(Toxicity Chart)



毒性图(Toxicity Chart) (1),顾名思义是一种展示代码毒性的方法。这个图代表了代码库中每个类的毒性,毒性分数是根据一系列参数计算出来的,比如文件长度、方法长度、循环复杂度、嵌套语句等等。这个图表可以展示给业务人员、管理人员等非技术人员,帮助他们了解代码的质量。


  1. https://erik.doernenburg.com/2008/11/how-toxic-is-your-code/


示例代码


下面的 Github 仓库包含了一个包含上述所有工具的示例项目。它的结构让你很容易选择一些需要的工具来集成到你自己的项目中。


https://github.com/singhalkul/java-quality-checks


保持代码质量是一个持续的过程,它不能由团队中的某一个人来完成,整个团队都有责任确保编写的代码是高质量的。


虽然上面提到的工具会帮助确保减少代码中一些质量问题,但这不是唯一的方法。团队应该遵循极限编程实践,如配对编程、测试驱动开发、代码审查、持续集成,以确保高质量代码特征存在于代码库中。


英文原文:

https://medium.com/inspiredbrilliance/improving-code-quality-for-java-projects-5d24ad448109


参考阅读:








高可用架构
改变互联网的构建方式