В чем разница между наблюдателем и подписчиком?

Я пытаюсь расшифровать следующую функцию:

Subscription getCar(id, Observer<Car> observer) {
    return getCarDetails(id, new Observer<CarDetails> {
                             @Override
                             onNext(CarDetails details) {           
                                 observer.onNext(details.getCar());
                             } });
}

Я получил хорошее введение в rxjava от http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/, но в нем упоминается только Observer мимоходом, говоря, что вы будете использовать Subscriber большую часть времени для потребительских товаров, отправляемых из Observable.

Кто-нибудь может мне объяснить

  1. Что такое наблюдатель?
  2. Чем обозреватель отличается от подписчика?
  3. Что делает приведенный выше фрагмент кода?

Javadoc сделал его похожим на подписчика. В javadoc для подписчика говорится, что он реализует наблюдателя и подписку. Я очень смущен.


person MarcusH    schedule 27.12.2014    source источник
comment
Это шаблон Observer по сравнению с опубликовать / подписаться. Они похожи, но имеют небольшие различия.   -  person Sean Patrick Floyd    schedule 27.12.2014
comment
@SeanPatrickFloyd: Вы можете объяснить различия?   -  person user541686    schedule 27.12.2014
comment
Что такое переменная "детали"?   -  person Marian Paździoch    schedule 14.04.2016


Ответы (4)


EDITED: с комментарием @ Alrid

tl; dr

public abstract class Subscriber<T> implements Observer<T>, Subscription

Итак, подписчик является реализация Observer, с дополнительной семантикой по подписке (это больше об отказе от подписки). Код в вашем вопросе просто показывает, что он передает интерфейс Observer, а не реализацию (обычная практика программирования).

Также этот код возвращает Subscription, это может быть связано с тем, что автор этого кода считал, что клиент должен иметь доступ только к Subscription методам, без доступа к элементам, созданным наблюдаемым объектом. Это может быть ошибка программиста.

длинная история

На самом деле вам следует прочитать содержание этого веб-сайта (или книги): http://www.introtorx.com Это о Rx.Net, но концепции те же самые, они были созданы Эриком Мейджером, и разработчики RxJava следовали их (если применимо к языку Java).

Эта страница вас заинтересует (это вторая глава): KeyTypes < / а>

Здесь вы прочтете в первых абзацах:

При работе с Rx необходимо понимать два основных типа и подмножество вспомогательных типов, которые помогут вам более эффективно изучить Rx. IObserver и IObservable образуют фундаментальные строительные блоки для Rx, а реализации ISubject сокращают время обучения для разработчиков, плохо знакомых с Rx.

...

По сути, Rx построен на основе паттерна Observer. .NET уже предоставляет некоторые другие способы реализации паттерна Observer, такие как многоадресные делегаты или события (которые обычно являются многоадресными делегатами).

Даже если типы / API немного отличаются, вы многому научитесь из этой книги, возможно, намного больше, чем из некоторых блогов.

О чем не говорится в этой книге (... потому что она находится в реализации RxJava)

Главный разработчик RxJava в это время представил небольшую вариацию (см. PR # 792), которая позволила различают два типа договоров:

  • уведомление -> Observer
  • (от) подписка -> Subscription

Это изменение позволило лучше выразить / разделить эти проблемы реализующих классов библиотеки RxJava.

Однако для пользователя библиотеки использование реальных реализаций библиотеки RxJava должно быть достаточно хорошим.

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


Предоставление Subscriber, а не Observer в таких случаях, как указано выше, в большинстве случаев не будет мешать работе кода, но это не является его предполагаемым использованием, если только эта семантика отмены подписки не требуется. Но, в конце концов, реализация Subscriber может повлечь за собой некоторые подводные камни, такие как:

  1. тратить ресурсы на функциональность, которую вы не будете использовать
  2. не может наследовать от другого класса
  3. напишите неверный код отмены подписки
  4. скопировать / вставить код неправильный код или правильный код, написанный для другого контекста
person Brice    schedule 27.12.2014
comment
В 2.x Observer используется для подписки на Observable, а Subscriber используется для подписки на Flowable, Subscriber больше не реализует Observer, github.com/ReactiveX/RxJava/issues/4515 - person sarvesh chavan; 02.09.2020

(Изменить: это, по-видимому, верно только для RxJava 1.)

  1. Observer - это объект, который может получать данные из источника данных (Observable). Источник данных отправляет в него данные, вызывая onNext() наблюдателя.

  2. Subscriber - это Observer, который также может отказаться от подписки на этот источник данных (через интерфейс Subscription).

  3. Функция getCar() пытается вернуть машины, но прямого метода для этого нет. Но есть функция для получения информации об автомобиле (getCarDetails()), которая вызывает наблюдателя со всеми подробностями об автомобиле. Таким образом, он вызывает эту функцию и передает ей наблюдателя, который при получении данных извлекает данные об автомобиле из деталей и передает их своему собственному наблюдателю.

person Lawrence Kesteloot    schedule 06.10.2015
comment
Это не так, поскольку в RxJava 2 подписчик и наблюдатель - это два совершенно разных интерфейса. Ни один не расширяет другой - person frankelot; 16.07.2017


Также в RxJava2, если вы хотите иметь возможность отказаться от подписки, вы должны использовать ResourceObserver для Observable и ResourceSubscriber для Flowable.

Проверьте этот вопрос

person Beshoy Fayez    schedule 16.06.2017