Перегрузка в отображении потока? - PullRequest
0 голосов
/ 29 января 2019

Я хочу для потоковой передачи событий нескольких событий, унаследованных от одного и того же базового типа, из mongoDB, используя пружину ReactiveMongoRepository.Далее я хочу, чтобы все они обрабатывались по-разному, и, таким образом, было определено несколько перегрузок метода handle, все для одного потомка.Тем не менее, компилятор жалуется, он не может найти правильный метод.

Проблема показывается в этом тестовом методе:

@Test
public void polymorphismTest() {
    this.createFlux()
            .map(this::polymorphicMethod)
            .subscribe();
}

private Flux<A> createFlux() {
    A1 a1 = new A1();
    a1.string1 = "foo";
    A2 a2 = new A2();
    a2.string2 = "bar";
    return Flux.just(a1, a2);
}

private void polymorphicMethod(A1 a1) {
    System.out.println(a1.string1);
}

private void polymorphicMethod(A2 a2) {
    System.out.println(a2.string2);
}

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

Я знаю, что решением было бы определить дескриптор как абстрактный метод вбазовый тип и реализуйте его в унаследованных классах, но это нарушит функциональный подход остальной части приложения, плюс события в базе данных должны быть POJO.

Я также хотел бы избежать типичного подхода к шаблону командс одним огромным отображением типов в функции, но если нет другой идеи, это может быть решением.

1 Ответ

0 голосов
/ 29 января 2019

Вы можете использовать Spring для предоставления типов, которые помогут Reactor сортировать соответствующие «события» в соответствующие «обработчики событий».

Например, вы можете определить следующее:

public interface EventListener<E extends EventType> {
    default Class<E> getType() {
        return (Class<E>) GenericTypeResolver.resolveTypeArgument(getClass(), EventListener.class);
    }

    Mono<Void> execute(E event);
}

ВыТеперь можно сделать следующее:

EventListener<E> listener = ...
sourceFlux.ofType(listener.getType()).flatMap(listener::execute)

С помощью Spring вы можете определить несколько EventListener экземпляров (либо создав классы, наследуя его, и используя @Component, либо определив @Configuration со многими @Bean экземплярами этогоинтерфейс), который вы можете собрать с помощью @Autowire или @Bean, чтобы «зарегистрироваться» для этих событий.

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

...