5

我试图了解 Cyclomatic Complexity 的工作原理以及如何避免警告。是的,我知道编写代码的目的不是避免任意警告,但我至少想知道发生了什么,这样我就可以决定我看到的代码是好是坏。

我有一个看起来像这样的函数:

protected function update($uuid, $data, $householdUuid, $androidId) {
    $household = $this->householdService->getHouseholdByUuid($householdUuid);

    $this->updatePeriod($household, $data);
    $this->updateNickname($household, $data, $androidId);
    $this->updateDateOrder($household, $data);
    $this->updateCurrency($household, $data);
    $this->updateAccounts($household, $data);

    $household->save();
    return $this->respondUpdated();
}

这被标记为具有 10 的圈复杂度。这怎么可能?从文档中,我将其视为 1。唯一的可能性是 PHPMD 正在下降到各种方法调用中。

但如果是这样,那么我没有办法“修复”这种方法。一般来说,我会通过提取更小的辅助方法来降低方法的复杂性。这个方法已经被重构为那些不同的 update() 方法,以消除发生的一堆条件更新。原始方法的圈复杂度也为 10,重构什么也没做。

或者问题可能更简单——我正在通过与 Jenkins 建立的持续集成来运行 PHPMD。PHPMD 没有使用最新的代码会不会有问题?在我已经将类重构到行数限制以下之后,我遇到了一些类似的问题,它会将一个类标记为有太多行。

4

2 回答 2

4

我可能认为每个函数调用都会增加 +1 的复杂性,因为它在技术上是通过代码,但根据文档不应该这样做。即使是圈复杂度的定义也不支持这个计数。

我认为这是 PHP Mess Detector 中的一个错误,因为 PHP_CodeSniffer 复杂度计算并没有给出 10 分。

于 2013-12-12T19:36:21.663 回答
3

我认为它是一个错误。我没有隔离它——但我将我的一个函数折叠为 {return false} 并重新运行 jenkins 工作。我的 NPath 复杂度仍然为 4000(ish)。当我从命令行运行 phpmd 时,它正确计算了它。

仔细研究一下,phpmd 依赖于 pdepend,而 pdepend 做了一些缓存。如果您直接运行 pdepend,您可以在配置中指定“内存”或“文件”缓存。但我不知道它如何或是否可能影响 phpmd 如何使用它。我想也许重新启动詹金斯会清除事情 - 但事实并非如此。一旦我的功能被标记为“过于复杂” - 这似乎会继续存在。

github 上的 phpmd 存储库中有一些关于缓存的问题。但这一切都有些模糊。如果我将其隔离为可重现的错误而不是我的设置的一些怪癖,我将提交错误报告。

于 2015-03-05T00:13:15.013 回答