我试图了解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的圈复数。这怎么可能?从the documentation开始,我将其视为1.唯一的可能是PHPMD正在下降到各种方法调用。
但如果是这样,那么我无法“修复”这种方法。通常,我会通过提取较小的辅助方法来降低方法的复杂性。这个方法已经被重构到那些各种update()方法中,以消除一堆发生的条件更新。原始方法的圈复杂度也为10,而重构没有做任何事情。
或者问题可能更简单 - 我正在通过与Jenkins的持续集成运行PHPMD。可能是PHPMD没有使用最新代码的问题?我有一些类似的问题,它会将一个类标记为有太多行,在我已经重构了行数限制以下的类之后。
答案 0 :(得分:2)
我可能认为每个函数调用都是为复杂性添加+1,因为它在技术上是通过代码,但它根据文档不应该这样做。即使Cyclomatic Complexity 的定义也不支持此计数。
我认为这是PHP Mess Detector中的一个错误,因为PHP_CodeSniffer复杂度计算没有给出10。
答案 1 :(得分:2)
我认为这是一个错误。我没有把它隔离出来 - 但是我把我的一个函数折叠到了{return false}并重新运行了jenkins的工作。我的NPath复杂度仍为4000(ish)。当我从命令行运行phpmd时,它正确地计算了它。
再看一下,phpmd依赖于pdepend,pdepend会进行一些缓存。如果直接运行pdepend,则可以在配置中指定“内存”或“文件”缓存。但我不知道如何或是否可能影响phpmd如何使用它。我想也许重新启动jenkins会清除事情 - 但事实并非如此。一旦我的功能被标记为“过于复杂” - 这似乎与它保持一致。
github上关于缓存的phpmd repo中存在一些问题。但它有点模糊。如果我将其隔离为可重现的bug而不是我的设置的一些怪癖,我会提交错误报告。