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); 
}