Зарегистрируйтесь, чтобы продолжить обучение

Guard Expression JS: Функциональное программирование

Одни функции устроены сложнее других. Иногда так происходит в силу объективных причин (необходимая сложность). Иногда — в силу особенностей писавшего ее программиста (случайная сложность). И хотя нельзя однозначно описать эту сложность, существуют способы, позволяющие хотя бы частично ее оценить.

Цикломатическая сложность

Цикломатическая сложность — это структурная или топологическая мера сложности компьютерной программы, разработанная Томасом Дж. Маккейбом в 1976 году.

Цикломатическая сложность части программного кода — количество линейно независимых маршрутов через программный код. Если исходный код не содержит никаких точек ветвления или циклов, то сложность равна единице, поскольку есть только один маршрут через код.

Если код имеет единственный оператор if, содержащий простое условие, то существует два пути через код: один, если условие оператора if имеет значение true, и один — если false.

Цикломатическая сложность

Такую оценку можно применять как в целом к программе, так и к отдельным функциям.

// Complexity: 1
const sum = (a, b) => a + b;
sum(1, 3); // 4

// Complexity: 2
const abs = n => (n >= 0 ? n : -n);

abs(10); // 10
abs(-3); // 3

В примере выше у функции sum цикломатическая сложность равна единице, а у функции abs — двойке, так как она содержит ветвление, а значит два независимых пути выполнения.

Чем больше возможных путей выполнения, тем сложнее функцию понять, отладить и модифицировать. Очевидно, что, с одной стороны, функции нужно дробить, а с другой — описывать логику программы так, чтобы не появлялись лишние пути. Даже опытные разработчики часто сталкиваются с этой проблемой.

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

Guard Expression

Подход, который мы изучим, также называемый «паттерном», помогает лучше структурировать функцию и иногда сократить цикломатическую сложность. Рассмотрим пример:

const f = (age, sex) => {
  if (age >= 18) {
    if (sex === 'male') {
      return 'yes';
    }
    if (sex === 'female') {
      return 'no';
    }
  }

  return null;
}

В этой функции вам все должно быть знакомо. Она принимает на вход возраст и пол. Для людей старше 18 в зависимости от пола возвращает строчку "yes" или "no". Для всех остальных — "null". В целом, с этой функцией все нормально, но кое-что можно улучшить.

Условие "вернуть null, если младше 18 лет" гораздо более простое и очевидное. Оно не подразумевает дальнейшего разветвления и сформулировано просто. Этим можно воспользоваться и произвести рефакторинг (улучшение работающего кода без изменения функциональности) таким образом, чтобы это условие отрабатывало первым.

const f = (age, sex) => {
  if (age < 18) {
    return null;
  }

  if (sex === 'male') {
    return 'yes';
  }

  if (sex === 'female') {
    return 'no';
  }
}

Обратите внимание на то, что уровень вложенности понизился. Основная логика находится вне условных конструкций. В такой реализации функции сложнее ошибиться: все, что пишется ниже guard expression (первая проверка в данном случае), попадает под требование "от 18 и старше", а в первом примере код для этого условия нужно не забывать вставить внутрь соответствующего условия.

Нам уже знаком такой подход. Терминальные условия в рекурсиях выглядят точно так же.

В будущих практиках и в реальной жизни он встречается повсеместно. Используйте его осознанно и понижайте энтропию.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»