代码质量 代码分析
本文采用非常简单和常识的方法来提高代码质量。 目的是揭开代码质量的神秘面纱,并帮助项目团队选择对他们有意义的流程和工具。
仅为了包含本文的范围,我将其余讨论限制为企业场景中基于Java / J2EE的技术项目。 质量的基本定义和确保方法的定义在使用其他技术栈并在非公司环境(例如,开源领域)中运行的技术项目中应相似。
谁应该关心代码质量?
让我们从快速调查表开始:
- 您是否交付和/或审查用Java编写的代码?
- 您是否管理/更新/配置任何用Java编写的第三方产品?
- 您是否在具有遗留代码的任何Java项目中贡献代码?
- 您是否在任何具有大量类(例如超过100个)的Java项目中贡献代码,并且希望掌握这些类的相互依赖性?
- 您是否有兴趣评估给定的Java项目中是否存在结构性问题?
如果对所有这些问题的答案是肯定的,则您应该关心代码质量。
事实的真相是,您可能尚未意识到它,并且代码质量(测量,确保,交付)可能不会在您的角色和职责中显示为不同的项目。 但是,如果不加以解决,它将赶上并引起悲痛只是时间问题。 主动处理此怪物的方法要好得多。
什么是高质量代码?
如果您用谷歌搜索或进行讨论,通常会得到两种类型的答案。
第一类是通用性(灵活性,可重用性,可移植性,可维护性,可靠性,可测试性等)。 尽管它们很重要,但对于如何精确地测量它们以及如何精确地对其进行改进尚不总是很清楚。
第二类是高度特定的技术参数,例如,环复杂度,传入耦合,传出耦合等。有记录良好的数学公式可以计算这些参数,软件可以为您计算出这些参数,并且相对容易获得具体的可行方法以改善这些参数数字。 但是,将数量的改进转换为代码质量的改进仍然是一项专门技能。
因此,净净,没有简单的答案。 让我们尝试改变它。 让我们提出一系列问题-从常识上讲-编写/维护高质量代码库的团队中的任何人都应该能够肯定地回答。
问题1:您有信心在添加新代码时不会破坏现有的可用功能吗?
您/您的团队是否签入代码? 我认为可以肯定地说,是的。 您的团队的普通开发人员每天是否会多次签入代码? 让我们假设是的。 您的团队的普通开发人员在一天的工作中,是否有可能在他的头上知道其他所有开发人员已经签入的内容以及这些代码段应如何工作? 不会。即使您的团队中有牛顿和爱因斯坦,也很重要。 因此,当编码人员疯狂地编写代码时,如何确保它们实际上没有破坏创建的更多内容呢?
答案应该是单元测试。 覆盖尽可能多的代码,以供单元测试使用。 ( 如果您的回答还有其他问题,请在文章中对此发表评论吗?我很想听听您的建议。 )
有一个自动的方法可以每天早上向团队中的每个人报告所有单元测试的成功情况。 如果单元测试失败,则修复它们将是当天的最高优先级。
每天早上还向团队中的每个人自动报告代码覆盖率。 理想情况下,代码覆盖率应在每个报告中增加。 至少它应该保持不变。 如果没有任何报告,则暂停一切并进行调查。
我的常识说,这必须是最重要的代码质量度量和过程。 ( 同样,如果您有不同的意见,请发表评论。 )幸运的是,整理一下这一点是相对容易的。 只需使用以下工具集:
- 单元测试框架: JUnit , TestNG
- 单元测试覆盖率工具: EclEmma , Cobertura
- 构建工具: Maven , Ant
- 持续集成工具: Jenkins , TeamCity
- 报告的Web仪表板: Sonar
我并不是说这是唯一/最佳答案。 我的意思是,如果您没有更好的答案,那么这个答案很简单,免费并且有效。
注意事项之一。 很多时候,当团队以此为起点时,某人或其他Google就会发现高质量的产品应该具有80%的单元测试覆盖率。 相比之下,该产品的状态要差得多。 这具有许多影响,包括士气和政治问题。 在此必须强调的一点是,孤立地覆盖80%的代码并不能保证任何事情。 真正重要的是制定适当的工作流程并不断提高测试范围。
问题2:在添加新代码时,您确定不会犯通常编码人员所犯的同样愚蠢的错误吗? 例如,您是否释放了最后一块中的所有资源?
任何编码的人都会犯错误。 如果编译器为您找到它们并吐出堆栈跟踪信息,您将很幸运。 但是,那些编译器没有抓住但编码社区了解的东西是不好的代码。 如果您十年前使用过银行软件,那么捕获愚蠢错误的唯一方法是让团队中的一位资深人士来审查您的代码。 事情并没有太大改变。 您仍然应该多看一眼代码和设计。 但幸运的是也有一些帮助。 您可以使用以下工具集:
- 任何源代码分析器: PMD , Checkstyle , Findbugs , Crap4j
- 构建工具: Maven , Ant
- 持续集成工具: Jenkins , TeamCity
- 报告的Web仪表板: Sonar
同样,我并不是说这是唯一/最佳答案。 我的意思是,如果您没有更好的答案,那么这个答案很简单,免费并且有效。
注意事项之一。 从这些项目开始的大多数项目都被这些源代码分析器标记的数百(如果不是数千)项目所淹没。 在这些工具上花一些时间并节制报告非常重要。 幸运的是,向这些源代码分析器添加/删除规则非常容易,可以对其进行有效配置,以仅报告您/您的团队认为值得举报的内容。 诀窍是确保规则与您的团队相关,并最大程度地尊重报告。 如果这些工具不断报告很多问题,并且团队中没有人确信它们是相关的,或者没有人确定应该由谁来解决这些问题,那就不好了。
我将在这里结束本文的第1部分。 我认为,我们在本文中讨论的前几个问题是最重要的。 任何认为对处理代码质量有所重视的技术项目都应首先采用它们。 下一部分将涉及高级主题,例如结构分析,突变测试等。
结构分析
在这篇有关“代码质量”的文章中,我将特别讨论“软件结构的质量”。
这些文章序列的主题采用非常简单和常识的方法来处理代码质量。 目的是揭开代码质量的神秘面纱,并帮助项目团队选择对他们有意义的流程和工具。
我将尝试使文章尽可能简单。 但是,听众知道,这个主题(即“软件代码的结构分析”)已经并且继续是相当涉及的主题。 数学家和计算机科学家早在1970年代就发表了关于该主题的开创性著作。
幸运的是,在公共领域中可以找到有关此主题的一些优秀材料。 我特别想谈一谈我在本文中使用的数据所高度依赖的以下作品。
1.“复杂性度量”,发表于IEEE交易软件工程,VOL。 托马斯·麦凯布(Thomas J.
2.“面向对象设计的度量套件”在IEEE交易软件工程,第1卷上发布。 20号 1994年6月6日,作者:Shyam R. Chidamber和Chris F. Kemerer。 3.罗伯特·马丁(Robert Martin)于1994年发表的“ OO设计质量度量标准,一项对依赖关系的分析 ”。 4.罗伯特·马丁(Robert Martin)发布的“ 设计原理和设计模式 ”。
在以下各节中,让我尝试介绍我对这些作品的解释要点。
模式让我们从列举不良代码结构的基本基本模式开始。 这些本质上是直观的,没有数学或科学定义。
结构缺陷的模式 | 定义和解释 |
---|---|
刚性 | 该软件很难更改。 |
易碎性 | 在软件的一部分中进行更改会导致软件上概念上无关的部分损坏。 |
不动 | 由于代码没有足够的模块化,因此很难在代码的各个组件之间移动。 |
黏度 | 错误的做法在软件中根深蒂固,因此继续进行错误的做法比引入正确的做法要容易得多。 |
不透明度 | 该系统很难理解。 |
矩阵矩阵是可测量的具体项目,具有科学和数学定义。 提供了标准工具,这些工具将针对您的代码库进行度量。 当然,此处提供的矩阵或工具列表并不详尽。
矩阵 | 定义和解释 | 工具类 |
---|---|---|
班级数量 | 如果在具有相同功能的项目之间进行比较,则可以更好地抽象出具有更多类的那些项目。 您可能希望保持该数字不变。 有效地遵循OOP概念应该会有所帮助。 | 声纳 (免费,开源) |
代码行(LOC) | 如果在具有相同功能的项目之间进行比较,则那些具有较少代码行的项目将具有出色的设计,并且所需维护更少。 | 声纳 (免费,开源) |
儿童人数(NOC) | 它是一个类的直接子类的数量。 尽量保持低调。 其他类变得太复杂了。 | 斯坦4J |
班级回应(RFC) | 这是该类中实现的所有方法的数量加上该类的对象由于实现而可访问的方法的数量。 尽量降低它。 RFC越高,进行更改的工作就越多。 | 声纳 (免费,开源), Stan4J |
继承深度树(DIT) | 从类到根类的最大继承路径。 尝试将其保持在5以下。 | 斯坦4J |
每类加权方法(WMC) | 类中定义的平均方法数。 尝试将其保持在14岁以下。 | 斯坦4J |
对象类之间的耦合(CBO) | 一个类与之耦合的类数。 尝试将其保持在14岁以下。 | 斯坦4J |
缺乏方法的凝聚力(LCOM4) | 它衡量一个类中“连接的组件”的数量。 较低的值表明该代码更简单且可重用。 较高的值表示应将班级细分为较小的班级。 如果此矩阵大于2,请尝试分解类别。 | 声纳 (免费,开源), 斯坦4J |
圈复杂度(CC) | 测量通过模块的不同可执行路径。 通过代码执行的可执行路径数量越多,意味着需要花费更多的精力进行完整的测试。 这反过来使理解和改变变得更加困难。 尝试将此值保持在10以下。 | JDepend (免费,开源) |
距离(D) | 距A + I = 1的理想化线的距离。软件与理想化线的距离越小,则效果越好。 抽象度(A)= Na / Nc。 不稳定性(I)= Ce /(Ce + Ca)。 | JDepend (免费,开源), Stan4J |
因此,矩阵就在其中,报告阈值和工具也随处可见。 如果您阅读了我在本文开头引用的材料,则会发现更多的矩阵。 我可以安全地建议至少使用Sonar和Sonar报告的基本矩阵。 那是任何企业级软件都应该至少拥有的。
正如我在该序列的第一篇文章中提到的那样,首先要进行测量。 与构建时进行的同一项目的图进行比较,并进行小的增量更改。 在正确的方向上努力朝正确方向迈出的小步伐,将会创造奇迹。 只是不要为了大杀戮,反对所谓的“行业标准”,一切都应该没事。
超越矩阵
在充分考虑矩阵的情况下,它们的效用仅限于对现有代码进行运行状况检查。 鉴于矩阵的数量和用于测量它们的工具过多(技术专家对工具和矩阵的功效添加了相互矛盾的观点),这很快就会造成混乱。 这就像看着管理面板,所有拨盘和灯泡都发疯一样,而您却疯狂地试图找出如何安抚所有人。 您还需要一个工具来分析所有这些矩阵,并直接指出代码中复杂而易受攻击的部分。 当然,如果它具有直观的可视界面,那么它会有所帮助。 有一些软件可以做到这一点(不幸的是,它们都不是免费的)。 我曾经使用过并且非常喜欢Structure 101 。 它报告“胖”包,类,设计等,这是说它认为“胖”工件过于复杂,因此尝试重构/重组的候选方法。 这些工件通常具有缠结(循环相关性),并且该工具确实很出色,并且表现得很好。
这使我结束了本文的结尾。 总之,我只想说,创建简单的代码是一项复杂的业务。 这不是(唯一的)劳动。 是技巧。 和所有技能一样,精通交易的工具也很重要。 知道从免费开源工具包中挑选哪些工具,以及为哪些工具付费(因为它们值得)是至关重要的。
在下一篇文章中,我们将讨论为项目创建将来的状态体系结构(假设它是一个长期运行的支持和升级项目),以及如何衡量代码库与将来的状态体系结构之间的一致性。
在那之前,快乐的编码。
参考: 常识和代码质量–第1部分 , 常识和代码质量–第2部分,来自我们的JCG合作伙伴 Partho在Tech for Enterprise博客上。
翻译自: https://www.javacodegeeks.com/2012/07/common-sense-and-code-quality.html
代码质量 代码分析