Здравствуйте, сегодня я хочу продемонстрировать, как вы можете улучшить устаревшую функцию, используя функциональное мышление. Я использую Vavr для примерной реализации. Примечание: В Java 11 есть некоторые из этих конструкций, но моя цель – запустить это Java 8.
Описание проблемы
Допустим, вы используете библиотечный метод для вычисления чего-либо. По какой-то причине он терпит неудачу чаще, чем вы ожидали в своей среде. Таким образом, ваша задача состоит в том, чтобы улучшить его, добавив несколько попыток вместо того, чтобы потерпеть неудачу с первой попытки. По сути, ваших пользователей устраивает задержка ответа, но больше вероятность получения результата.
Пример реализации функциональной повторной попытки
import java.util.function.Consumer; import java.util.function.Supplier; import io.vavr.Tuple; import io.vavr.Tuple2; import io.vavr.collection.Stream; import io.vavr.control.Option; import io.vavr.control.Try; public class FunctionalRetry { public staticOption of(int maxTries, Supplier theWorker, Consumer >> statusReporter) { return Stream.range(0, maxTries) .map(it -> Tuple.of(it, Try.ofSupplier(theWorker))) .peek(statusReporter) .find(result -> result._2.isSuccess()).map(t -> t._2.get()); } public static Option of(int maxTries, Supplier theWorker) { return of(maxTries, theWorker, input -> System.out.println("Iteration:" + input._1 + "> Result:" + input._2)); } }
Класс, демонстрирующий, как использовать функциональность
import java.util.Random; import io.vavr.control.Option; public class Main { public static void main(String[] args) { OptionmayBe = FunctionalRetry.of(10, Main::doSomething); if (mayBe.isDefined()) System.out.println(mayBe.get()); } //Samepl test function public static int doSomething() { if (new Random().nextInt(5) != 0) throw new NumberFormatException(); return 1; } }
Это оно. Вы можете увидеть функциональность.метода, который принимает функцию, в данном случае это поставщик, количество повторных попыток и дополнительная функция наблюдения, которая сообщает о статусе каждого вызова вызывающему.
Это может быть реализовано с помощью циклов, но это добавит больше путей к коду и дополнительной сложности. Но эта реализация даже не заботится о базовом методе.
Этот код также доступен на github gist Вдохновение для моего поста пришло от всех людей, которые говорят о функциональном программировании, Программирование Пола Грэма снизу вверх является одним из них.
Вывод
На мой взгляд, по сравнению с императивным стилем, функциональный стиль дает программисту лучший контроль над тем, где ставить границы и кто за что отвечает. Традиционно мы всегда говорим, что разработчик, внедривший базовый метод, должен убедиться, что все сценарии были рассмотрены перед отправкой, что невозможно в современных информационных технологиях. Поэтому используйте функциональный стиль везде, где только можете, чтобы облегчить себе жизнь программиста. Получайте удовольствие и продолжайте учиться.
Примечание
Я знаю, что стиль и читабельность не самые лучшие, поэтому в следующий раз я поделюсь той же реализацией с использованием Kotlin.
Оригинал: “https://dev.to/guntaka/functional-way-of-adding-retry-logic-to-a-java-method-3noi”