Общая помощь в определении интерфейса - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть набор API, для которых я создаю реактивную версию, используя проект-реактор

Мой существующий интерфейс похож на

  Profile getProfile(String accessToken);

  Profile getProfileByEmail(String adminToken, String email);

  Token validateToken(String accessToken);
  ...

Вариант реактора проекта будет

  Mono<Profile> getProfile(String accessToken);

  Mono<Profile> getProfileByEmail(String adminToken, String email);

  Mono<Token> validateToken(String accessToken);
  ...

Другим вариантом будет

  CompletableFuture<Profile> getProfile(String accessToken);

  CompletableFuture<Profile> getProfileByEmail(String adminToken, String email);

  CompletableFuture<Token> validateToken(String accessToken);
  ...

Я хочу определить суперинтерфейс, используя обобщенные значения для вышеприведенного API.

Любая помощь по определению интерфейса без необходимостипоможет разобраться с непроверенными исключениями.

1 Ответ

2 голосов
/ 08 ноября 2019

Нет разумного способа создать общий интерфейс для этих трех классов. (Вы могли бы, но тип возвращаемого значения должен был бы быть Object, что, вероятно, не делает его слишком полезным.) Это также относится и к сервисам "реального мира" - SqsClient и SqsAsyncClient - это просто блокирующие / неблокирующие клиенты для одной и той же службы, но ни одно из определений метода «операция» не происходит из общего интерфейса.

Если вы действительно должны иметьвсе доступные варианты, и вы можете добавить другие в будущем, наиболее разумная вещь, которую можно сделать здесь, это, вероятно, реализовать службу фактический с использованием CompleteableFuture, а затем внедрить другие службы с использованием этой службы. Это, вероятно, дает вам наиболее совместимый вариант продвижения вперед:

class BlockingProfileService {

    CompletableFutureProfileService service;

    public BlockingProfileService(CompletableFutureProfileService service) {
        this.service = service;
    }

    Profile getProfile(String accessToken) {
        return service.getProfile(accessToken).get();
    }

    //..etc..

и:

class ReactorProfileService {

    CompletableFutureProfileService service;

    public ReactorProfileService(CompletableFutureProfileService service) {
        this.service = service;
    }

    Mono<Profile> getProfile(String accessToken) {
        return Mono.fromFuture(service.getProfile(accessToken));
    }

Вы, конечно, можете использовать какой-то другой шаблон, чтобы вам не нужно было проходить через CompleteableFutureProfileService напрямую, который может быть создан с необходимыми параметрами в другом сервисе.

Однако, я боюсь, что здесь вы можете усложнить ситуацию. Если вы просто используете реактор повсюду (что означает, что реактор уже должен быть зависимостью), тогда просто придерживайтесь Mono - нет необходимости смешивать Mono и CompletableFuture, и, конечно, нет необходимости поддерживать устаревшую блокировкуAPI (так как его можно легко получить, заблокировав любую асинхронную библиотеку.)

...