- Избавляемся от конкретизации интерфейса CompletionStage. Тру реакционщики пишут свои интерпретации.
- Абстрагируемся от возвращаемого значения посредством интерфейса или абстрактного классаю Например DBResponse. Завтра вам надоест мускул, уйдете в носкул. Достаточно будет интерфейс переписать.
- Унифицируем получение данных, вынося в сигнатуру метода однотипные переменные. queryAsync Завтра смените DSL на jooq - достаточно будет только один метод переписать.
- Постарайтесь избавиться от JOIN. Очень дорогой метод, грубо приводящий реактивное программирование к императивному. Используйте thenAcceptAsync, exceptionallyAsync, handleAsync Метод result()
public CompletionStage<DBResponse> query1(){
return queryAsync(jdbc, sql, param1, param2, ... paramN);
}
public CompletionStage<DBResponse> query2(){
return queryAsync(jdbc, sql, param2, param3, ... paramN);
}
public CompletionStage<DBResponse> queryAsync(JDBC jdbc, sql, Objects ... params){
return CompletableFuture.supplyAsync(() -> {
return jdbc.query(sql, params);
}).thenApplyAsync(DBResponse::of);
}
// далее в коде
void result(){
CompletableFuture.allOf(query1(), query2())
.thenAcceptAsync( ... );
}
public static interface DBResponse {
default DBResponse of(Response resp){
...;
}
}
P.S. Ничего не написал про
concurency, не знаю, как вы используете. Имхо удобно инстанцировать отдельный пул на каждый тип операций (disk, http, sql, ui, ...).