Я новичок в функциональном программировании (и Java), и я хочу создать что-то приятное с его помощью, но не могу понять, как это сделать.Повторить один раз с помощью функционального интерфейса
Я использую BiConsumer (java.util.function.BiConsumer) для вызовов на сервер.
Я пытаюсь написать код, который отправляет некоторый запрос серверу с существующими данными (вызов Public createSomeTask()), только если он не работает, соединитель выполнит повторную попытку только один раз.
Код isync, Private createSomeTask() вызывает updateTaskStage().
Проблема заключается в том, что у меня много вызовов в коннекторе (много createSomeTask()) с текущей реализацией, код не выглядит хорошо, и я уверен, что есть способ сделать это лучше, используя функциональные интерфейсы или расширяя BiConsumer или любой другой хороший способ в Java 8 lile, отражение, метод invoke и т. Д.
См. Код ниже. Надеюсь, кто-то может мне помочь.
//Main
public class Main {
public static void main(String[] args) throws InterruptedException {
Connector connector = new Connector();
connector.createSomeTask("started",(response, error)->{
});
}
}
//Connector Class
import java.util.function.BiConsumer;
public class Connector {
static String taskStage = null;
public void createSomeTask(final String taskName,
final BiConsumer<ServerResponse, ServerError> consumer) {
createSomeTask(taskName, true, consumer);
}
private void createSomeTask(final String taskName,
boolean retry,
final BiConsumer<ServerResponse, ServerError> consumer) {
updateTaskStage((newStage, error)->{
if(error!=null) {
if (retry) {
createSomeTask(taskName, false, consumer); //The 'recursive' retry call
return;
} else {
consumer.accept(null, error);//only after second failure
return;
}
}
consumer.accept(new ServerResponse(),null);
});
}
//re-uses existing task or starting a new one when the current is null/failed
private void updateTaskStage(final BiConsumer<String, ServerError> consumer) {
if(taskStage ==null || taskStage != "failed")
consumer.accept(taskStage,null);
else
{
taskStage = "started";
consumer.accept(taskStage,null);
}
}
class ServerResponse{}
class ServerError{}
}
Ваш код уже использует BiConsumer (функциональный интерфейс), лямбда-выражения, так что еще вы хотели бы сделать. Если вы ищете какое-то асинхронное решение, я бы предложил изучить CompletableFuture –
Да, но проблема здесь заключается в уродливом рекурсивном вызове с параметром «повторить», установленным в true или false. Я ищу способ, возможно, расширить BiConsumer, чтобы добавить, возможно, первого потребителя в качестве поля, которое будет автоматически вызываться – Igal