Найти тему
Bereshpolov

Удаление блоков if-else и функциональный полиморфизм

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

Одиночный if-else
Одиночный if-else

Приведенный выше код понятен и прост, но давайте заменим его тернарным оператором:

Тернарный оператор
Тернарный оператор

Но как можно упростить множественный if-else со статическим результатом?

-4

Приведенный выше код также не оказывает никакого негативного влияния на читаемость кода. Мы можем оставить все как есть, или, если нам совершенно не нравится использовать if-else, мы можем заменить из на Map<>.

Замена блоков if-else на HashMap
Замена блоков if-else на HashMap

Как видите, особой разницы в коде нет. Посмотрим на этот код:

-6

Приведенный выше код имеет потенциал роста, количество скидок может измениться. Понимая это мы видим, что может возникнуть несколько новых правил, которые могут нарушить Open Close Principle.

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

Все блоки условий внутри метода похожи, и имеют две вещи:

  • Условие для оценки, которое должно возвращать логическое значение.
  • Блок для выполнения возвращает определенный тип (скажем, общий тип T).

Давайте создадим класс с двумя параметрами.

condition:Supplier<Boolean> - принимает условие и возвращает логическое значение
process:Supplier<T> - принимает блок операторов и возвращает тип T
-7

Так же создадим представление для каждого условия с помощью Enum. Итак, у нас есть три условия:

  • TEN_PERCENT_DISCOUNT
  • FIVE_PERCENT_DISCOUNT
  • ONE_PERCENT_DISCOUNT
-8
Внимание, очередность Важна!

Теперь, создаем метод для создания правила на основе условия и процесса. Тип возвращаемого значения для каждого блока - Double. Таким образом, получаем тип возвращаемого объекта Rule<Double>.

-9

И создаем правила, для различных представлений.

-10

Первый параметр, это условие, второй параметр это расчет ответа.

Теперь создаем HashMap всех представлений вместе с правилами, для упрощения вычислений.

-11

Для вычисления результата используем Stream, применяем к нему фильтр с условиями указанными в HashMap.

-12

Мы можем провести дальнейший рефакторинг того же кода и применить возврат по умолчанию.

Класс Rule<T> можно применить к любой замене условия в приложении.

Пишите комментарии, оставляйте лайки и подписывайтесь, если Вам понравилась статья.

Источник: https://muthuishere.medium.com/java-if-else-removal-functional-polymorphism-673e25a6a5ae