在工作中,我们使用多种工具来捕获多个指标(主要是圈复杂度和 LCOM)。我们使用这些来获取警告标志并指导先发制人的重构工作。它对提高代码质量非常有益。
但是,该过程与构建过程无关。它是分开进行的。此外,我正在寻找可以使源代码固有的东西(而不是在其上运行的外部进程。)
有没有人知道一组可以从编译器运行的注释和可配置的注释处理器,如果代码不符合阈值圈/LCOM 指标,这将使构建失败?
我想我可以从 maven/ant 运行 ckjm、checkstyle 和 pmd,但是一些工作在源代码上,其他工作在字节码上。在编译开始之前有一个可以处理源代码的整合工具会很好。
另一件事是,如果有一组注释可以推动这一点,那就太好了(允许在极端情况下不可避免地需要定制。)
@LCOM3(Threshold=1.5)
public class SomeDumbPojo {... buch of gets/sets...}
// by default would be measured against a strict LCOM3
public class ActualBizClass
{
@CYCLOMATIC_COMPLEXITY(Threshold=15)
public void someFatIrreducibleMethod(){...}
}
Run Code Online (Sandbox Code Playgroud)
然后,当我们运行该工具时,默认情况下会应用严格的(和可配置的)指标阈值,除了那些用(希望有记录且合法的)更宽松的阈值进行注释的工件。对于一些不能/不应该减少的方法,放宽的圈复杂度是有意义的。对于没有行为的普通 POJO,LCOM 需要放松……等等等等。
尽我所能寻找和谷歌搜索,我找不到任何东西(希望是开源的)。但我不妨在这里问一下,以防万一有人知道这类事情。
谢谢。
考虑以下三个函数,它们都以相同的方式运行,使用不同的代码来实现相同的事情(示例是用JavaScript编写的,我对应用于JavaScript的答案特别感兴趣,但这个问题可能真的适用于任何具有类似结构的语言):
// Random number from 0-9
var x = Math.floor(Math.random() * 10);
// JSHint reports a cyclomatic complexity of 3
function a() {
if (x === 0) {
return "First";
} else if (x === 1 || x === 2) {
return "Second";
}
return "Third";
}
// JSHint reports a cyclomatic complexity of 4
function b() {
switch (x) {
case 0:
return "First";
case 1:
case 2:
return "Second";
default:
return "Third";
}
}
// JSHint reports a …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
private Facility updateFacility(Facility newFacility, Facility oldFacility) {
if (newFacility.getCity() != null)
oldFacility.setCity(newFacility.getCity());
if (newFacility.getContactEmail() != null)
oldFacility.setContactEmail(newFacility.getContactEmail());
if (newFacility.getContactFax() != null)
oldFacility.setContactFax(newFacility.getContactFax());
if (newFacility.getContactName() != null)
oldFacility.setContactName(newFacility.getContactName());
// ......
}
Run Code Online (Sandbox Code Playgroud)
大约有 14 个这样的检查和分配。也就是说,除了少数,我需要修改 oldFacility 对象的所有字段。我得到了这个代码 14 的圈复杂度,根据 SonarQube,这是“授权大于 10”。关于如何降低圈复杂度的任何想法?
ESLint 报告了难以忍受的高复杂性。我想知道为什么它太复杂了?如果我把它分成多个函数会发生什么——这样性能好吗?据我所知,我们总是必须编写精简的代码,因此如果我们将其拆分为多个函数,它将消耗更多的空间(位)和更多的执行时间?
处理这个片段的最佳实践是什么?
const getWeekType = (f, d, e) => {
const y = moment(),
a = moment(f),
i = moment(d);
if (d && f && i.diff(a, 'days') <= 8 && y.diff(a, 'days') < 8 && y.diff(a, 'days') >= 0) {
return { weekNum: 0, dayNum: y.diff(a, 'days') };
}
if (f && y.diff(a, 'days') >= 0 && y.diff(a, 'days') < 8 && (!d || i.diff(a, 'days') > 8)) {
return { weekNum: 1, dayNum: y.diff(a, 'days') };
}
if …Run Code Online (Sandbox Code Playgroud) Cyclomatic Complexity提供了一个粗略的指标,用于了解给定函数的难易程度,或者包含错误的可能性.在我已经阅读过的实现中,通常所有基本的控制流构造(if,case,while,for等)都会使函数的复杂度增加1.在我看来,圈复杂度旨在确定"通过程序的源代码的线性独立路径的数量",虚函数调用也应该增加函数的圈复杂度,因为在运行时将调用哪个实现的模糊性(调用在路径中创建另一个分支)执行).
但是,如果它包含一个等效的switch语句(每个'case'关键字一个点,对于实现所讨论的虚函数的层次结构中的每个类都有一个case关键字),那么惩罚函数的量就会过于苛刻,因为虚函数调用通常被认为是更好的编程实践.
虚拟函数调用的圈复杂度的成本应该是多少?我不确定我的推理是否反对将圈复杂度作为衡量虚拟函数或不同东西的度量的指标.
编辑:在人们的回答之后,我意识到它不应该增加圈复杂性,因为我们可以认为虚函数调用等同于对包含大量switch语句的全局函数的调用.即使该函数得分较差,它只在程序中存在一次,而用switch语句直接替换每个虚函数调用会导致成本很多次.
language-agnostic virtual-functions cyclomatic-complexity code-metrics switch-statement
如何找到具有多个出口点的函数的圈复杂度?维基页面显示p-s + 2,其中p是决策点的数量,s是退出点的数量.
但是,不应该有更多的出口点增加圈复杂度,因为它可能导致更独立的路径?
干杯,
祖阿曼
我对几个项目运行了静态代码分析,并从生成的报告中获取了这些项目中每个文件的循环复杂度。现在我想计算整个项目的平均圈复杂度。
我怎样才能最好地实现这一目标?
对我来说,仅将每个文件的循环复杂度值相加然后除以文件数似乎是错误的,因为短头文件与很长的文件具有相同的影响。另外,我想避免通过代码行来衡量文件的重要性。
还有其他方法吗?例如,用中位数?
int maxValue = m[0][0];
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if ( m[i][j] >maxValue )
{
maxValue = m[i][j];
}
}
}
cout<<maxValue<<endl;
int sum = 0;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
sum = sum + m[i][j];
}
}
cout<< sum <<endl;
Run Code Online (Sandbox Code Playgroud)
对于上面的代码,如果我们绘制这样的流程图
基本独立路径将遵循六
路径1:1 2 3 10 11 12 13 …
metrics cyclomatic-complexity code-metrics path-finding unstructured-loop
我已经使用C#在.NET中开发了一个应用程序。
使用“计算代码度量”选项,我得到了2,348行代码的循环复杂度得分为“ 267”,继承深度= 7,类耦合= 150,可维护性指数= 80。
我知道圈复杂度越低越好。尽管我不知道其余的参数,但我想知道267的圈复杂度是否更好?
我有以下场景,其中有多个 if else 条件。
以下代码的圈复杂度显示为 7。
是否有更好的方法来使用 Javascript 编写以下代码片段以降低代码的复杂性?
function setTime() {
var currentTime = "3/4/2020, 2:53:42 PM"
var selectedTime = "3/5/2020, 2:53:42 PM"
if( Date.parse(currentTime) < Date.parse(selectedTime)) {
callThisMethod('Current time less than selected time');
} else if (Date.parse(currentTime) > Date.parse(selectedTime)) {
callThisMethod('Current time Greater than selected time');
} else {
callThisMethod('Current time is equal to selected time');
}
}
function callThisMethod(message) {
console.log(message);
}
setTime();
Run Code Online (Sandbox Code Playgroud) code-metrics ×3
javascript ×3
metrics ×3
java ×2
.net ×1
annotations ×1
c# ×1
eslint ×1
path-finding ×1
performance ×1
sonarqube ×1