Esiste una best practice per l'utilizzo di ListenableFuture
di Guava nei parametri nelle chiamate API? Confronta queste due versioni di un'interfaccia che internamente fa un confronto-e-set (sto usando il ListenableFuture
di Guava):
interface MyDao {
ListenableFuture<Data> getData(String id);
ListenableFuture<Boolean> updateData(ListenableFuture<Data> data, int newFieldValue);
}
interface MyDao {
ListenableFuture<Data> getData(String id);
ListenableFuture<Boolean> updateData(Data data, int newFieldValue);
}
La prima sembra un po 'caotica, e l'implementazione probabilmente coinvolgerà un Futures.transform
del proprio, ma si potrebbe anche sostenere che si tratta di un'API asincrona, quindi prendere i future in quanto i parametri potrebbero avere senso. Dove è bello è che riordina la logica di business quando si utilizza l'interfaccia in modo che legga come codice sincrono:
ListenableFuture<Data> data = dao.getData("123");
ListenableFuture<Boolean> success = dao.updateData(data, 10);
Confrontalo con
ListenableFuture<Data> data = dao.getData("123");
ListenableFuture<Boolean> success = Futures.transform(data, (Data d) -> dao.updateData(d, 10));
E questo è con un lambda. È orribile in Java 7.
L'ovvio inconveniente è che l'interfaccia sembra incoerente. Perché data
è un futuro, ma newFieldValue
non lo è? Anche il id
dovrebbe essere un futuro? Accanto a queste linee, rende una chiamata banale incredibilmente complicata, quasi come gli oggetti wrapper Java prima dell'autoboxing.
Inoltre non fa nulla per ripulire le orribili tracce dello stack quando i futures falliscono; sono ancora in cascata ogni transform
.