JavaRush /Java блог /Random /Избегаем лишней вложенности в циклах
ZloyLis
58 уровень
Брест

Избегаем лишней вложенности в циклах

Статья из группы Random
Делая первые шаги в изучении программирования, многие новички сталкиваются с ветвлением и начинают писать длинные вложенные циклы. К примеру, возьмем ситуацию, когда нам нужно дать пользователю доступ к кошельку (isAccess()). Мы вводим следующие две проверки: 1) Пользователь залогинен 2) Пользователь идентифицирован За проверки у нас отвечает результат методов isLogin() и isIdentify(). Они возвращают логические true или false. РАЗРАБОТЧИК И МАКАРОННАЯ ФАБРИКА Да, ничего сложного в задаче нет. Пишем проверки, если прошла первая проверка (isLogin()) - движемся ко второй(isIdentify()). Если все проверки прошли успешно - даем доступ к кошельку(isAccess()). Вот как обычно это выглядит у новичков: Избегаем лишней вложенности в циклах. - 1 Мы получили вложенные проверки. Сейчас у нас всего две проверки, а если их четыре, пять или более? У кода с такой архитектурой есть жирный минус - его неудобно читать, в нём бывает сложно разобраться. БУДЬ ПРОЩЕ Перед нами стоит задача написать код проще и понятнее. Как это сделать? Да как два байта переслать 😉. Необходимо избавиться от вложенных проверок, заменив их проверками с противоположными условиями. В Java для этого есть специальный логический оператор НЕ (!)(логическое отрицание). Он меняет логическое значение операнда с истины на ложь и наоборот. Смысл наших действий в том, чтобы прописать не условия, когда нужно что-то делать, а условия, когда чего-то ДЕЛАТЬ НЕ НУЖНО и стоит завершить программу. Т.е., мы пишем своеобразный фейсконтроль, если входные данные условиями не вышли - мы сразу же завершаем программу. Обычно это делается следующим образом: 1) В условии проверки меняют значение на противоположное с помощью логического оператора (!). 2) Если это условие выполняется (т.е. мы получили неподходящие входные данные), то программа сразу же останавливается. 3) Все ранее вложенные друг в друга условия делают невложенными и размещают друг под другом. Перепишем наш код: Избегаем лишней вложенности в циклах. - 2 Теперь наша логика работает следующим образом: 1) Пользователь не залогинен? Выходим из функции. 2) Пользователь не идентифицирован? Выходим из функции. 3) Даем достум тем, кто не вышел на всех предыдущих этапах. Таким образом мы получаем: 1) Код стало легче читать. 2) В код можно легко внести новые проверки или убрать ненужные. Как видим, немного изменив код, мы сделали его более понятным и чистым. А значит, стали еще ближе к качественному коду. Но, на всякий случай помним: "Хорошо задокументированный баг, автоматически становится фичей!" Спасибо за внимание!
Комментарии (4)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Денис Уровень 37
13 марта 2024
А при чем тут циклы если не секрет?) Ну и по кодстайлу пара замечаний, названия методов очень плохо говорят о том что они делают. Например wallet.isAccess() это что? префикс is обычно ставится перед булевыми методами или полями, например

if (session.isAlive()) { /*doSomething*/ }
Но общая идея вполне здравая. Хотя в данном конкретном примере можно было бы обойтись обычным &&

if (user.isLogin() && user.isIdentify())
А можно было бы на уровне юзера сделать отдельный метод для этих целей:

if (user.isAuthorized()) {}
В общем подходов хватает на самом деле. Главное чтобы код сохранял читаемость и модифицируемость.