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

85

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

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 для подписчика говорится, что он реализует наблюдателя и подписку. Я очень смущен.

MarcusH
источник
Это шаблон наблюдателя против публикации / подписки . Они похожи, но имеют небольшие различия.
Шон Патрик Флойд
4
@SeanPatrickFloyd: Вы можете объяснить различия?
user541686
Что такое переменная "детали"?
Marian Paździoch

Ответы:

65

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

tl; dr

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

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

Также этот код возвращает a 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. скопировать / вставить код неправильный код или правильный код, написанный для другого контекста
Брайс
источник
1
В 2.x Observer используется для подписки на Observable, а Subscriber используется для подписки на Flowable, Subscriber больше не реализует Observer, github.com/ReactiveX/RxJava/issues/4515
sarvesh chavan
40

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

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

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

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

Лоуренс Кестелут
источник
2
Это не так, поскольку в RxJava 2 подписчик и наблюдатель - это два совершенно разных интерфейса. Ни продляет другой
FRR
19

В RxJava 2 org.reactivestreams.Subscriber есть интерфейс, соответствующий спецификации Reactive Streams .

Основное отличие от Observableновинки в том, что она Subscriberподдерживает противодавление.

Observerподписан Observableи Subscriberподписан Flowable(реализует org.reactivestreams.Publisher).

См. Подробное описание здесь .

Ярослав Ставничий
источник
3

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

Отметьте этот вопрос

Бешой Файез
источник