0

我是功能编程(和Java)的新手,我想用它创建一些不错的东西,但无法弄清楚。使用功能接口重试一次

我正在使用BiConsumer(java.util.function.BiConsumer)调用服务器。

我试图写一个代码,它向现有数据发送一些请求到服务器(调用Public createSomeTask()),只有当它失败时,连接器才会执行一次重试。

代码是async,private createSomeTask()也调用updateTaskStage()。

问题是我在连接器(许多createSomeTask()) 与当前的实现有很多调用,代码看起来不好,我相信有一种方法可以更好地使用Functional接口或扩展BiConsumer或Java 8 lile,反射,方法调用等任何其他好方法。

请参阅下面的代码。 我希望有人能帮助我。

//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{} 
} 
+0

你的代码已经在使用BiConsumer(函数接口),lambda表达式,所以你还想做什么。如果您正在寻找一些异步解决方案,我建议您去探索CompletableFuture –

+0

是的,但这里的问题是“retry”参数设置为true或false的丑陋递归调用。 我正在寻找一种方式来扩展BiConsumer,以便将第一个消费者添加为将自动调用的字段 – Igal

回答

0

没有理由来检查消费者的retry标志,你可以将它传递给updateTaskStage之前组成一个功能做正确的事:

private void createSomeTask(
    String taskName, boolean retry, BiConsumer<ServerResponse, ServerError> consumer) { 

    BiConsumer<String, ServerError> direct 
     = (s, e) -> consumer.accept(e==null? new ServerResponse(): null, e); 

    BiConsumer<String, ServerError> actual = retry? 
     (string, error) -> { 
      if(error!=null) updateTaskStage(direct); else direct.accept(string, null); 
     }: 
     direct; 

    updateTaskStage(actual); 
} 

首先,创建一个函数传递后端对提供的消费者的回应的翻译。

然后,只有当retrytrue时,该函数由另一个函数组成,该函数将在错误情况下进行第二次尝试。对于第二次尝试,可以将直接函数传递给updateTaskStage,不需要递归。

因为它似乎retry参数不应该是一种选择,但只有你解决问题的尝试的一部分,你现在可以摆脱它,当始终执行一个重试的目的是:

public void createSomeTask(
    String taskName, BiConsumer<ServerResponse, ServerError> consumer) { 

    BiConsumer<String, ServerError> direct 
     = (s, e) -> consumer.accept(e==null? new ServerResponse(): null, e); 

    BiConsumer<String, ServerError> actual= 
     (string, error) -> { 
      if(error!=null) updateTaskStage(direct); else direct.accept(string, null); 
     }; 

    updateTaskStage(actual); 
}