簡體   English   中英

異步完成創建的Java對象 - 對象在構造函數完成后的某個時間准備就緒

[英]Java object that completes creation asynchronously - object is ready some time after constructor finishes

我必須將專有的java api包裝成更有用的東西。 中心類是“客戶端”對象簽名是這樣的:

public class ProprietaryClient {

    private final IEvents eventHandler;
    private Object one;
    private Object two;

    public ProprietaryClient(ProprietaryClient.IEvents eventHandler){
        this.eventHandler = eventHandler;
    }

    //returns immediately
    public void connect(String url){
        //doing nasty stuff that triigers
        //on success
        //will be called from somewhere at anytime
        // eventHandler.onStateChange( State.CONNECTED );
    }

    //returns immediately
    public void login(String user, String password){
        //doing nasty stuff that sets fields one and two
        //will be called from somewhere at anytime
        //eventHandler.onStateChange( State.LOGGED_IN );
        //eventHandler.onLogin( one, two );
    }

    public interface IEvents {

        void onStateChange(State state);

        void onLogin(Object one, Object two);
    }

    public enum State{
        CONNECTED,
        LOGGED_IN,
        UNKNOWN;
    }
}

此對象僅在狀態“LOGGED_IN”中有用,但此字段沒有getter。 了解對象是否可用的唯一方法是:

  1. 呼叫連接
  2. 等待狀態更改為CONNECT
  3. 呼叫登錄
  4. 等待狀態更改為LOGGED_IN(或調用onLogin)

我想將它包裝成一個連接並在構造函數中登錄的類,並告訴用戶它是否准備就緒。 我的想法是有一個返回CompletableFuture或Future的方法:這是我到目前為止所擁有的。 事件的東西就是這樣的。 IEvents的實現將所有evants包裝成由用戶標識的消息(這部分正在工作)。 但是如何根據到達事件創建和維護CompletableFuture(帶有/// ????的部分)有沒有辦法創建我自己的未來,如果事件到達或滿足正確條件就可以准備好?

public class MyClient implements Client, MessageHandler {


    private final String password;
    private final IEvents eventHandler;
    private final SubscribableChannel eventBus;
    private final String user;
    private final ProprietaryClient propClient;

    public SikomClient( String user, String password, IEvents eventHandler, SubscribableChannel eventBus) {
        this.eventHandler = checkNotNull( eventHandler );
        this.eventBus = checkNotNull( eventBus );
        eventBus.subscribe( this );
        this.password = password;
        this.user = user;
        propClient = new ProprietaryClient(eventHandler);
        ///????
        propClient.connect("url");
        //have to wait until message received and state is "CONNECT"
        propClient.login(user, password);

    }

    public CompletableFuture<Boolean> amIready(){
        //???
    }

    @Override
    public void handleMessage( Message<?> message ) throws MessagingException {
        if( message instanceof OnClientStateMessage && belongsToMe( message )){
            // ????
        } else if( message instanceof OnLoginMessage && belongsToMe( message )) {
            // ????
            //complete CompletableFuture with true
        }
    }

    private boolean belongsToMe(Message<?> message){
        return ((AbstractStringJsonMessage) message).getUserId().equals( user );
    }
}

或者,沒有“未來”,有沒有更好的方法來解決這個問題。 我想讓調用者有責任等待多久但我的班級應該保持狀態並了解它。

解決方案相當簡單。 現在我更了解“CompletableFuture”。

我添加了一個登錄方法,一個具有Completable future的字段,它是一個getter:

private CompletableFuture<ReturnCode> loggedIn = new CompletableFuture<>();
...
private void login() {
    //as per sikom settings each user gets a fixed workplace identified by user name
    if( loggedIn.isDone() ) {
        loggedIn = new CompletableFuture<>();
    }
    propClient.login( user, user, password, 0 );
}

public CompletableFuture<ReturnCode> loggedIn() {
    return loggedIn;
}

我的handleMessage執行此操作:

public void handleMessage( Message<?> message ) throws MessagingException {
    if( message instanceof OnClientStateMessage && belongsToMe( message ) ) {
        state = ( (OnClientStateMessage) message ).getState();
        if( state.equals( ClientState.CONNECT ) ) {
            login();
        }
    } else if( message instanceof OnLoginMessage && belongsToMe( message ) ) {
        ReturnCode rc = ( (OnLoginMessage) message ).getRc();
        loggedIn.complete( rc );
    }
}

如果消息到達,我只需手動完成未來(因為它沒有附加任務,get將永遠不會返回)。

此類的用戶將實例化它,並可立即調用loggedIn。 calle可以決定等待loggedIn.get()的時間。

不知道它是不是一個好主意:它自己的類可以擴展CompletableFuture並且可以自己完成?!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM