Найти тему
Журнал «Код»

Вкладываете условия в условия? Это для вас

Оглавление

Если вы вложили условие в условие, то, если вы прочитаете эту статью, будет счастье, иначе не будет, иначе не читайте

Это текст, который сдвигает вашу программистскую парадигму и существенно повышает качество кода.

Задача

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

Проверки такие:

  1. Подключён к Wi-Fi-сети.
  2. Вошёл в систему со своими логином и паролем.
  3. Есть админские права доступа.

За эти условия отвечают 3 логических переменных — wifi, login и admin. Проверка должна идти именно в этом порядке. Если одна из проверок не прошла, следующую можно не проводить.

Решение в лоб

Кажется, что написать код для этих проверок просто, и это на самом деле так: проверяем первое, если прошло — проверяем второе, если прошло — третье. Если всё прошло, то выводим панель управления. Если что-то не проверилось, сообщаем. Вот эти три проверки, вложенные друг в друга:

Упрощаем код

У кода со вложенными проверками есть минус: его неудобно читать и сложно сразу разобраться, что за что отвечает и где заканчивается каждая проверка.

Наша задача — сделать код понятнее, чтобы его было легко читать сейчас и поддерживать в будущем. Главное неудобство во вложенных проверках: трудно глазами следить, что за чем проверяется и что во что вложено.

Решение — избавиться от вложенных условий, заменив их условиями с противоположным значением, а именно:

было if (wifi) — «если в переменной wifi значение true»;

стало if (! wifi) — «если в переменной wifi не значение true, то есть false».

В английском языке это называется guard clauses. Устоявшегося перевода на русский пока нет, поэтому для простоты мы назовём это «охранные условия».

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

Для этого обычно делают так:

  1. В каждом условии меняют значение условия на противоположное.
  2. Если оно выполняется (то есть функция встретила неподходящее для неё значение), то всё сразу останавливается и функция дальше не идёт.
  3. Все вложенные условия делают обычными, невложенными, и просто размещают их друг под другом.

Покажем, как это работает, сначала на примере проверки подключения к Wi-Fi:

function access() {
// если НЕ подключён к Wi-Fi
if (!wifi) {
// выводим сообщение
console.log('Доступ возможен только при подключённом Wi-Fi');
// выходим из функции
return;
}
}

Теперь из кода видно, что если пользователь не подключён к Wi-Fi, то он получит сообщение об этом, а потом функция остановится. Это первый уровень защиты, когда мы проверяем первое условие для показа панели администратора.

Теперь это упражнение можно повторить для двух других условий. Логика будет такой:

  1. Я не подключён к Wi-Fi? Если не подключён, то выходим из функции.
  2. Я не вошёл в систему? Если не вошёл, то выходим из функции.
  3. У меня нет админских прав? Если прав нет, то выходим из функции.
  4. Показать админскую панель тем, кто не вышел из программы на всех предыдущих этапах.

Что дальше

Этот приём — один из многих, чтобы сделать код более чистым и понятным. В следующих статьях разберём постепенно и все остальные.