Pull to refresh

Количественная оценка понятности кода

Reading time3 min
Views18K
image

Принято считать, что понятность кода — вещь, во-первых, субъективная, а, во-вторых, — количественно не измеряемая. Существуют различные количественные метрики кода, но среди них метрики понятности нет. Чтобы машинно измерить понятность кода, нужен его семантический анализ, а это уже задача искусственного интеллекта.

Но давайте посмотрим на проблему с другой стороны. Что мы делаем, когда разбираемся с чьим-то кодом? Как происходит сам процесс изучения кода? Мы листаем функции, ищем определения переменных, классов, переходим от функции к функции, от файла к файлу.


Последние две задачи, которые я выполнял на работе, были связаны с анализом чужого кода и выдачей рекомендаций по его улучшению/переписыванию. Я только и делал, что переключался с файла на файл, переходил по классам, функциям и переменным, пытаясь понять их назначение.

Из этого родилась идея, как можно количественно оценить понятность кода. Суть очень проста: нужно измерить количество переходов и скроллов и нормировать их по количеству строк кода. Если оцениваем понятность функции, то и нормировать будем по количеству строк в функции. Аналогично и для класса, и для целого проекта. Согласно такой оценке, идеальным будет код, который достаточно пролистать один раз вниз. Или, в предельном случае, достаточно будет пролистать лишь одну главную функцию. Программный код должен быть подобен обычному тексту, который читается один раз линейно сверху вниз.

Вот несколько примеров навскидку, которые помогут понять суть этой метрики:
Пример 1: вы встречаете в коде переменную с ни о чем не говорящим названием (например, j). Вы найдете определение этой переменной (совершите переход), и, если повезет, там окажется комментарий, поясняющий, что она означает. Если не повезет, и комментария не окажется, то вам придется искать все места, где она используется (совершать переходы) и пытаться понять ее назначение. А если даже комментарий к переменной и был, то вы, вероятно, скоро забудете его, и придется снова к нему возвращаться (совершать переход).

Пример 2: в коде вы встретили вызов функции с ни о чем не говорящим названием. Более того, не понятно, какой результат может выдавать функция. Вам придется совершать переход к реализации этой функции, несколько раз перемотать ее вниз и вверх, чтобы понять, что она делает, и какой результат возвращает. А если функция окажется длиной строк в 200-300, то листать придется много.

Пример 3: в анализируемой функции присутствует множественная вложенность: условия в циклы, циклы в условия. Держать в памяти это очень сложно, и вы будете периодически пролистывать код вверх, чтобы удерживать весь контекст в памяти.

Пример 4: логически связанные функции как попало разбросаны по файлу или вообще находятся в других файлах. И чтобы найти реализацию вызываемой функции приходится листать, переходить, переключаться, теряя из памяти текущий контекст рассмотрения.

Пример 5 (не из реальной работы, гипотетический): Если мы слишком сильно увлечемся рефакторингом, каждое элементарное действие выделим в функцию/класс, то навигация по ним также может превысить все разумные пределы. Понятность кода также упадет, так как нужно будет очень много держать в памяти.

Таким образом, метрика включает в себя оценку:
  • названий переменных, функций, классов
  • размеров функций
  • вложенности
  • последовательности расположения функций в файле
  • избыточных комментариев, снижающих количество полезного кода на странице
  • использования паттернов,
то есть многих из тех критериев качества кода, о которых пишут в статьях и книгах по рефакторингу.

Предвижу вопрос, что такой способ оценки понятности не лишен субъективности. Соглашусь. Я вижу здесь две основные сложности.
Во-первых, кто-то привык часто переходить по коду, а кто-то способен держать контекст в памяти. Но все же этот способ более объективен, чем просто оценка, основанная на мнении. А, учитывая простоту реализации такой оценки, интересно было бы посмотреть результат.
А во-вторых, поначалу разработчики могут намеренно меньше (больше) листать код, чтобы получить желаемую оценку. Но когда такая проверка станет привычной практикой в организации, то, вероятно, подтасовки исчезнут.

Хочу сразу оговориться, что преложенный способ позволяет оценить только понятность кода (в том числе и качество интерфейсов), но не качество архитектуры, отсутствие дублирования, зависимости и т.д. То есть имеет смысл использовать его в сочетании с другими метриками и анализаторами кода.

Реализовано это может быть в виде плагина для IDE.
Tags:
Hubs:
+17
Comments34

Articles