Когда я только начинал программировать, хотел бы я, чтобы тогда нашёлся кто-то, кто мог бы рассказать об основных подводных камнях, с которыми я столкнусь при создании моего первого сайта.
Тогда одной из проблем было чрезмерное использование else при написании условных выражений. Сегодня я сам постоянно вижу, как в ту же ловушку попадают другие люди, поэтому решил написать этот пост.
Дисклеймер: нижеизложенное — исключительно моё субъективное мнение.
Приём, о котором я собираюсь рассказать, работает не всегда и иногда использовать else всё-таки придётся. В остальных случаях отказ от else поможет сделать код чище.
![](https://habrastorage.org/getpro/habr/post_images/92c/a8f/14d/92ca8f14dcf256994eb2560d603279f3.png)
Охранные выражения
Согласно Википедии, охранное выражение («guard clause») — предварительная проверка неких условий с целью избежать ошибок позже.
Давайте разберём вышенаписанное на пальцах. Итак, мы выполняем проверку неких условий (где-то в начале кода) чтобы не иметь дела с ошибками во время движения потока исполнения программы.
В идеале мы бы хотели, чтобы основная логика программы была расположена после всех проверок данных.
Давайте рассмотрим такой пример: сайт, где один из разделов доступен только премиум клиентам и только после 12 часов.
<?php
if ($user != null) {
if (time() >= strtotime('12 pm')) {
if ($user->hasAccess(UserType.PREMIUM)) {
if ($store->hasItemsInStock()) {
// Раздел доступен.
} else {
return 'We are completely sold out.';
}
} else {
return 'You do not have premium access to our website.';
}
} else {
return 'This section is not opened before 12PM';
}
} else {
return 'You are not signed in.';
}
В реальной жизни, мы скорее всего будем кидать исключения.
Хотя подход выше и выполняет задачу, уже трудно понять к какому конкретно условному выражению относится каждое else, хотя их пока всего несколько штук.
Можно представить, что начнётся для случая с гораздо более сложной логикой. Код станет совсем неподдерживаемым, так что надо искать альтернативный подход.
На помощь приходят охранные выражения:
<?php
if (condition1()) {
return ...;
}
if (condition2()) {
return ...;
}
// Входные данные в порядке.
doSomething();
Перепишем код нашего примера используя охранные выражения:
<?php
if ($user == null) {
return 'You are not signed in.';
}
if (time() < strtotime('12 pm')) {
return 'This section is not opened before 12PM';
}
if (!$user->hasAccess(UserType.PREMIUM)) {
return 'You do not have premium access to our website';
}
if (!$store->hasItemsInStock()) {
return 'We are completely sold out.';
}
// Раздел доступен.
При использовании охранных выражений, мы обычно инвертируем условия, которые проверяем. Т.е. если раньше мы проверяли, что пользователь залогинен, теперь будем проверять, что он НЕ залогинен.
Новый подход всё так же решает задачу, но получившийся код гораздо чище и понятнее.
Заключение
При создании программы, постоянно спрашивайте себя: «Насколько легко будет её изменить через 6 месяцев?»
Всегда приятно решить проблему быстро. Но написание кода без мыслей о том, как его поддерживать в будущем, просто безответственно.
Использование охранных выражений позволит вам и вашим коллегам модифицировать проверку данных быстрее и легче, когда это потребуется.