7.1.2. Цикломатическая сложность
На протяжении всей книги вы постоянно сталкиваетесь с термином «цикломатическая сложность». Это одна из редких метрик кода, которые я считаю полезными.
Вы могли подумать, что книга по программной инженерии будет полна метрик, но, скорее всего, уже поняли, что это не так. Можно создать мириады метрик кода60, но большинство из них будут бесполезны. Предварительные исследования показывают, что самая простая метрика — количество строк кода — лучше всего определяет сложность [43]. На этом этапе мне важно убедиться, что все читатели поняли суть.
Чем больше строк кода, тем хуже кодовая база. Количество строк кода — показатель производительности только в том случае, если вы измеряете количество удаленных строк. Чем больше строк вы добавите, тем больше кода придется прочитать и понять другим специалистам.
Хотя строки кода — довольно практичный показатель сложности, цикломатическая сложность полезна по другим причинам. Это удобный инструмент анализа, поскольку он не только информирует вас о сложности, но и помогает при выполнении модульного тестирования.
Думайте о цикломатической сложности как о количестве путей прохождения фрагмента кода.
Даже простейшая часть кода предоставляет единственный путь, поэтому минимальная цикломатическая сложность равна 1. Вы можете легко «вычислить» цикломатическую сложность метода или функции: начиная с единицы, считать, сколько раз встречается if и for. Для каждого из этих ключевых слов вы увеличиваете число (от 1).
Специфика подсчета зависит от языка программирования. Идея в том, чтобы подсчитать операторы ветвления и цикла. Например, в языке C# вам придется включать foreach, while, do и каждый case в блоке switch. В других языках ключевые слова для подсчета будут отличаться.
Какова цикломатическая сложность метода Post в системе резервирования столиков в ресторане? Попробуйте сосчитать все операторы ветвления в коде листинга 6.9, начиная с единицы.
Что вы получили?
Цикломатическая сложность кода листинга 6.9 равна 7. У вас получилось 6 или 5?
Давайте разберемся, как же получить 7. Не забудьте начать с единицы. Для каждого оператора ветвления увеличьте число на 1. Есть пять операторов if. Пять плюс один равно шесть. Последний оператор заметить труднее всего: это ??, оператор нулевого слияния, представляющий две альтернативные ветви: одну, где dto.Name имеет значение null, и другую, где это не так. Это еще один оператор ветвления61. Итак, всего метод Post содержит семь элементов.
Как я уже упоминал, я использую число семь как предельное значение кратковременной памяти мозга. Если вы определите пороговое значение, равное семи, метод Post из листинга 6.9 удовлетворяет ему впритык. Вы могли бы оставить все как есть. Это нормально, но если вам понадобится добавить восьмую ветвь, сначала придется провести рефакторинг. А еще у вас может не быть на это времени в будущем, поэтому если есть время сейчас, то лучше провести профилактический рефакторинг, не откладывая на потом.
Пока не забывайте об этом. В подразделе 7.2.2 мы еще вернемся к методу Post, чтобы провести рефакторинг. Но сначала давайте рассмотрим некоторые другие принципы.