Главная

Бросьте эти if-else в помойку.

Серьёзно, перестаньте их использовать.

Поделиться:
 

22+

Или просто: пишите чистый, поддерживаемый код без if-else

Наверное, вы уже прочитали бесчисленное множество руководств и учебников по программированию на том или ином языке, в которых многократно и настойчиво используются if-else. Также, очень вероятно, вы читали книги, в которых пропагандируется использование if-else как фактического метода ветвления.

Если вы грешите чрезмерным использованием if-else, то давайте пресечём это раз и навсегда, возможно, заменив if-else на объекты состояния. Этот подход обычно используется в классах с методами, реализация которых должна изменяться в зависимости от текущего состояния. Даже если вы уже слышали о шаблоне состояний, то будет невредно посмотреть на его реализацию. Для тех, кто все еще не в теме, вот небольшое введение:

Сложность кода возрастает с каждым if-else выражением. Применяя шаблон состояния, вы просто изменяете поведение объектов, используя специальные объекты состояния вместо операторов If-else.

Дни, когда код выглядел примерно так, давно прошли:

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

Если вы считаете, что создание новых классов вместо использования операторов ветвления усложняет код, то вы ошибаетесь. Классы состояния лаконичные и элегантные. Более того, это сделает ваш код более SOLID-ным, за исключением «D».

“Отлично, я понял, что If-else — зло, теперь покажите мне, как избежать беспорядочного ветвления?”

Хорошо, я продемонстрирую, как заменяется if-else условия на одном примере. Это выдуманный пример, но подход тот же, что я использовал на больших проектах. Давайте создадим очень простой класс Booking, у которого есть несколько состояний. У него также будет два public метода: Accept() и Cancel().

В меру своих возможностей я нарисовал диаграмму, которая отображает различные состояния, в которых может находиться Booking.

Реорганизация логики ветвления — трехэтапный процесс:

1. Для начала создайте абстрактный базовый класс состояния.
2. Реализуйте каждое состояние как отдельный класс, наследуемый от базового исходного.
3. Пусть у класса Booking есть private или внутренний метод, который принимает в качестве параметра базовый класс состояния.

Demo time

Во-первых, нам нужен базовый класс состояний, от которого будут унаследованы все состояния.

Обратите внимание, что базовый класс также имеет два метода, Accept и Cancel, хотя здесь они отмечены как внутренние. Кроме того, в базовом состоянии есть «особый» метод EnterState(Booking booking). Он вызывается всякий раз, когда объекту Booking присваивается новое состояние. Во-вторых, мы создаем отдельные классы для каждого состояния, которое хотим представить.

Image for post

Обратите внимание, как каждый класс представляет состояние, как следует из диаграммы выше. Кроме того, CancelledState не позволяет нашему booking перейти в новое состояние. Этот класс очень похож на шаблон Null Object.

Наконец, сам класс.

Image for post

Видите, как классbooking делегирует реализацию Accept и Cancel своему объекту состояния?
Это позволяет удалить большую часть условной логики и каждому состоянию сосредоточиться только на том, что важно для него самого — текущее состояние также имеет возможность перевести booking в новое состояние.

Как работать с новыми условными, так сказать, функциями?

Если раньше новая функция обычно была реализована с использованием некоторой проверки, теперь вы можете создать новый класс состояния. Это невероятно просто. Вам больше не придется иметь дело с громоздкими операторами if-else.

Как сохранить объект состояния в базе данных?

Объект состояния не важен при сохранении объекта в базе данных SQL или NoSQL. Важно лишь знать состояние объекта и то, как его следует сопоставить со столбцом. Вы можете сопоставить состояние с именем типа, enum`ом или int`ом. Выбирайте удобный вам способ конвертирования сохраненного значения обратно в объект состояния.

Вы все еще пользуетесь If`ами?

Да, иногда, они необходимы, особенно при использовании в качестве предохранительных условий. Но именно комбинация If-else является основной причиной проблем с поддерживаемостью кода.

Очень много дополнительных классов!

На самом деле. Как-то я для себя решил, что сложность связана не с количеством классов, которые у вас есть, а с обязанностями, которые эти классы берут на себя. Наличие множества специализированных классов сделает ваш код более читабельным, удобным в обслуживании и, в целом, более приятным для работы.

22+