Pergunta

Na minha aplicação, estou executando uma transação que pode estar em três estados diferentes no final da execução:

  • Sucesso
  • Falha
  • Pendente

Dependendo do estado, o cliente do aplicativo desejará executar ações diferentes. No caso de sucesso, eles desejam recuperar o resultado da transação (um widget). No caso de falha, eles desejam receber o motivo do erro. No caso de a transação estar pendente, eles desejam agendar um horário para tentar novamente. Atualmente, devolvo um objeto com os seguintes métodos:

public interface Result() {
     State getState();
     Widget getWidget(); // Success
     Reason getFailureReason(); // Failure
     Callable<Result> getTask(); // Pending
}

A idéia é que o cliente verifique o estado do objeto de resultado e invoca o método apropriado, dependendo do seu valor, por exemplo

if (result.getState() == State.PENDING) {
    result.getTask();
}

Eu estava pensando que poderia ser preferível usar um retorno de chamada, por exemplo,

public interface TransactionCallback() {
    void onFailure(Reason reason);
    void onSuccess(Widget widget);
    Delay onPending(Delay previous);
}

Onde Delay é uma classe representando um Timeunidade e período, permitindo que o aplicativo reagesse a execução da transação. Outra alternativa é lançar uma exceção que envolva o motivo da falha (pois só deve falhar em condições excepcionais) e manter o onSuccess e onPending métodos.

Então, minha pergunta é a seguinte: o uso de um retorno de chamada é um padrão apropriado para esse problema específico ou alguém pode sugerir algo mais apropriado?

Foi útil?

Solução

Eu não acho que este seja um bom uso do padrão de retorno de chamada.

Um retorno de chamada é apropriado se o Callee (por exemplo, a transação no seu caso) precisar continuar fazendo as coisas após o retorno do método de retorno de chamada. Mas se a próxima coisa que o Callee sempre faz é retornar ao chamador, o retorno de chamada não agrega valor. É apenas torna a estrutura do código mais complexa e menos legível. IMO, seria melhor retornar um objeto de resultado ou (no caso de uma falha excepcional) lançar uma exceção.

EDITAR - Re o comentário do OP.

Eu posso ver o valor de usar um método de retorno de chamada para perguntar ao chamador se a transação deve continuar, embora eu provavelmente tivesse usado um parâmetro simples de tempo limite. No entanto, o uso de métodos de retorno de chamada para retornar os resultados é (IMO) ainda está errado.

Outras dicas

Eu prefiro retornos de chamada Como se você o usar em vários lugares, isso resultará em menos código e será mais legível. Com a declaração de devolução da sua declaração para determinar o que vai acontecer (qual método ligar) estará no serviço fazendo a transação e todo o código que usa o serviço parecerá mais limpo.

Os argumentos de retorno de chamada devem incluir o objeto que fornece a chamada. Parece bom para mim, mas o uso de um retorno de chamada pode envolver alguns problemas de sincronização - você não pode ter certeza de qual estado receberá o retorno de chamada. Não é impossível, mas pode precisar de consideração.

Obviamente, com a pesquisa do resultado, você precisaria de sincronização do outro lado. Mas isso parece mais simples de sincronizar.

A solução de retorno de chamada é muito extensível, enquanto você pode, em um momento, mudar o comportamento para uma chamada assíncrona.

A desvantagem é que seu código será menos legível, especialmente para os programadores iniciantes. Se isso não é um problema para você, com certeza, continue ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top