Progettazione di un'API flessibile con supporto per le callback

5

Sto scrivendo una libreria Java che deve rendere http GET & & Richieste POST. Ci saranno due tipi di utenti di questa libreria:

  1. Quelli con la comprensione dei callback e sanno come usarli.
  2. Quelli che .... non.

Quindi considera i seguenti due metodi:

public void methodWithCallback(ServiceCallback callback) {
    try {
        // GET && POST code that cannot really be abstracted to a separate method
    } catch (IOException e) {
        callback.onError(e);
        callback = null;
    }
    callback.onSuccess(response);
    callback = null;
}

public Response methodWithoutCallback() throws IOException {

    try {
        // again, GET && POST code that cannot really be abstracted to a separate method
    } catch (IOException e) {
        logger.log(e);
        throw e;
    }
    return response;
}

Il codice precedente mi sembra sporco, principalmente perché ha duplicazione del codice per inviare la richiesta. Inoltre, se scrivessi un sacco di metodi del genere, il mio codice sarà molto presto raddoppiato a spaghetti difficilmente gestibili.

Ho preso in considerazione di consentire al client di impostare una richiamata fornendo un metodo come setCallback(Callback callback) e quindi avere un generale method che notifica il callback se NON è null. Ma anche questo sembra sporco perché scriverei un lotto di if null assegni!

Cosa ne pensi? Quale sarebbe il modello di design desiderabile qui che consiglieresti?

    
posta Joel Min 03.06.2016 - 02:54
fonte

1 risposta

2

Secondo me, puoi usare un metodo (per ogni funzione di servizio) e differenziare callbackful e callbackless versione consentendo o meno il richiamo di null da passare (idea 1) o utilizzando la richiamata per essere registrata da setCallback come la tua seconda idea (idea n. 2).

Richiamata come argomento (idea n. 1)

public Response method(ServiceCallback callback) throws IOException {
    try {
        // GET && POST code that cannot really be abstracted to a separate method
        /* In your code you handle the response outside the try block,
           it can raise NullPointerException because you set callback 
           to null, and onSuccess is also called even it is an error. */
        return handleSuccess(response, callback);
    } catch (IOException e) {
        /* Return statement is needed because the method signature requires it. */
        return handleError(e, callback);
        /* If you use this two line version below, you can make handleError 
           return void. */
        // handleError(e, callback);
        // return null;
    }
}

private Response handleSuccess(Response response, ServiceCallback callback) {
    if (callback != null) {
        callback.onSuccess(response);
    }
    /* I personally prefer to also return the result even the callback exists;
       otherwise just move the line below into if block and return null here. */
    return response;
}

private Response handleError(IOException e, ServiceCallback callback) throws IOException {
    if (callback != null) {
        callback.onError(e);
    } else {
        logger.log(e); /* because I assume you want to log it */
        throw e;
    }
    /* I assume there is no response if error occurred. */
    return null;
}

Richiamata come campo (idea n. 2)

public Response method() throws IOException {
    try {
        // GET && POST code that cannot really be abstracted to a separate method
        return handleSuccess(response);
    } catch (IOException e) {
        return handleError(e);
    }
}

private Response handleSuccess(Response response) {
    if (this.callback != null) {
        this.callback.onSuccess(response);
    }
    return response;
}

private Response handleError(IOException e) throws IOException {
    if (this.callback != null) {
        this.callback.onError(e);
    } else {
        logger.log(e);
        throw e;
    }
    return null;
}
    
risposta data 03.06.2016 - 05:58
fonte

Leggi altre domande sui tag