Почему этот код имеет высокую цикломатическую сложность или это ошибка в PHPMD в Jenkins?
Я пытаюсь понять, как работает 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, и рефактор ничего не делал.
Или, может быть, проблема проще - я запускаю PHPMD через непрерывную интеграцию с Дженкинсом. Может ли быть проблема, когда PHPMD не использует самый последний код? У меня были похожие проблемы, когда класс помечался как слишком много строк, после того как я уже рефакторинг класса ниже предела количества строк.
2 ответа
Я мог бы подумать, что каждый вызов функции - это то, что добавляет +1 к сложности, поскольку технически это - проход кода, но он не должен делать это в соответствии с документацией. Даже определение цикломатической сложности не поддерживает этот подсчет.
Я думаю, что это ошибка в PHP Mess Detector, так как вычисление сложности PHP_CodeSniffer не дает 10 на это.
Я думаю, что это ошибка. Я не изолировал его, но свернул одну из своих функций, чтобы {вернуть false}, и снова запустил задание Дженкинса. У меня все еще была сложность NPath 4000 (иш). Когда я запускал phpmd из командной строки, он правильно рассчитал его.
Рассматривая это немного подробнее, phpmd использует pdepend, а pdepend выполняет некоторое кэширование. Если вы запускаете pdepend напрямую, вы можете указать кеширование "memory" или "file" в конфигурации. Но я не знаю, как или возможно ли повлиять на то, как это использует phpmd. Я подумал, что, возможно, перезапуск Дженкинса прояснит ситуацию, но это не так. Как только моя функция была помечена как "слишком сложная" - это, кажется, остается с ней.
В репозитории phpmd на github есть несколько проблем, связанных с кэшированием. Но все это немного расплывчато. Если я выделю это как воспроизводимую ошибку, а не как причуду моей установки, я отправлю отчет об ошибке.