Рубрики
Без рубрики

Функциональный способ добавления логики повторных попыток в метод java

Здравствуйте, сегодня я хочу продемонстрировать, как вы можете улучшить устаревшую функцию, используя функциональное мышление. Я… Помечен как java, функциональный.

Здравствуйте, сегодня я хочу продемонстрировать, как вы можете улучшить устаревшую функцию, используя функциональное мышление. Я использую 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 static  Option 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) {
    Option mayBe = 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”