对于其中一个java项目,我们最近开始使用SonarLint。代码分析的输出显示了太多的关键代码嗅觉警报。
Critical code smell: Refactor this method to reduce its Cognitive Complexity.我听说过圈复杂性,但没有听说过认知复杂性。我向小组提出的问题:
我已经通过了这个链接,但无法得到所有问题的答案。
提前谢谢。
发布于 2017-10-11 14:30:21
人类可以很容易地记住大约7个实体+/- 2(维基百科)。当有人需要阅读代码时,他们可能会遇到这个限制。有时,有太多的局部变量来跟踪,或者太多的if/for语句。在所有情况下,这都会使理解代码应该做什么变得更加困难,因为很难对算法保持一个头脑中的图像。
行业标准:不。
可读性和可维护性:更容易调试/改进简单易懂的代码。
适用于方法或其他部分:一些人可能想要理解的一切。如果您试图解释您的设计,而我需要跟踪20+类,我会迷路的。如果我需要与您的界面快速工作,但我需要记住10位的状态,我将无法做到。
它所依赖的任何特定标准:要理解代码,需要记住的东西的数量。
最佳实践:创建更多和更好定义的功能。将相关概念提取到组/包中。减少代码中嵌套级别的数量(如果读取嵌套代码,则需要记住实现嵌套的条件)。在任何一点上减少使用中变量的数量(在提取函数时效果很好)。
发布于 2022-07-07 05:47:43
如果您正在编写“旧样式”java,那么代码复杂性是一个有用的度量标准,这意味着大量的ifs和循环。当您正在编写更多的“新样式”java时,使用流、筛选器、映射、约简和其他lambdas,认知复杂性并不是很有用。
例如,我有一个大约350行的有效行,有35种方法,总的认知复杂度为14,我向您保证,代码比几个循环和ifs更难理解。实际上,这35种方法中有25种的认知复杂度为0.
编辑:添加示例
例如,该方法的认知复杂度为0:
public Mono<Void> handle(WebSocketSession session) {
return session
.send(events
.filter(this::shouldBeIncluded)
.map(this::toJsonText)
.map(session::textMessage))
.and(session
.receive()
.map(WebSocketMessage::getPayloadAsText)
.map(this::handleMessage));
}这是‘新风格’java,使用链式调用、流等,因为这种认知复杂性不太有用。虽然这段代码比使用像if(shouldBeIncluded(event)) { ... }这样的语句的“旧”代码更容易阅读,但是这种方法的认知负载仍然不是零。
圈复杂度基本上是路径计数除以方法计数,其中认知复杂性试图变得更聪明,例如,增加更多的惩罚更深的嵌套。对于“新样式”代码来说,它就不那么有效了。
https://stackoverflow.com/questions/46673399
复制相似问题