У чому різниця між спостерігачем і передплатником?


83

Я намагаюся розшифрувати таку функцію:

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

Хтось може пояснити мені

  1. Що таке спостерігач?
  2. Чим спостерігач відрізняється від передплатника?
  3. Що робить наведений вище фрагмент коду?

Javadoc зробив це схожим на передплатника. Javadoc для абонентів каже, що реалізує спостерігача та підписку. Я дуже розгублений.


Це шаблон Observer проти публікації / підписки . Вони схожі, але мають тонкі відмінності.
Шон Патрік Флойд

4
@SeanPatrickFloyd: Чи можете ви пояснити відмінності?
user541686

Що таке змінна "деталі"?
Marian Paździoch

Відповіді:


63

ВИДАВАНО : з коментарем @ Alrid

tl; д-р

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

Отже, Subscriber - це реалізація Observer , з додатковою семантикою підписки (це більше стосується відмови від підписки). Код у вашому запитанні просто показує, що він передає Observerінтерфейс, а не реалізацію (звичайна практика програмування).

Також цей код повертає a Subscription, це може бути тому, що автор цього коду вважав, що клієнт повинен мати доступ лише до Subscriptionметодів, без доступу до елементів, створених спостережуваним. Це може бути помилкою програміста.

довга історія

Дійсно, вам слід прочитати зміст цього веб-сайту (або книги): http://www.introtorx.com Мова йде про Rx.Net, але концепції збігаються, їх створив Ерік Мейєр, а розробники RxJava слідували їм ( якщо застосовується до мови Java).

Ця сторінка вас зацікавить (це другий розділ): KeyTypes

Тут ви прочитаєте перші абзаци:

Існує два ключових типи, які слід зрозуміти при роботі з Rx, і підмножина допоміжних типів, які допоможуть вам вивчити Rx ефективніше. IObserver і IObservable складають основні будівельні блоки для Rx, тоді як реалізації ISubject зменшують криву навчання для розробників, нових для Rx.

...

По суті, Rx побудований на основі шаблону Спостерігача. .NET вже пропонує деякі інші способи реалізації шаблону Observer, такі як делеґати багатоадресної передачі або події (які зазвичай є делегатами багатоадресної передачі).

Навіть якщо типи / API дещо відрізняються, з цією книгою ви дізнаєтесь багато нового, мабуть, набагато більше, ніж із деякими блогами.

Про що ця книга не говорить ( ... тому що вона знаходиться у реалізації RxJava )

На даний момент головний розробник RxJava ввів невелику варіацію (див. PR # 792 ), що дозволило розрізнити два типи контрактів:

  • повідомлення -> Observer
  • (не) передплата -> Subscription

Ця зміна дозволила краще виразити / розділити ці заклопотаності щодо реалізації класів бібліотеки RxJava.

Однак, як користувач бібліотеки, використання фактичних реалізацій бібліотеки RxJava має бути достатньо хорошим.

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


Викриття, Subscriberа не Observerу таких випадках, як вище, у більшості випадків не заважатиме коду, але воно не призначене для нього, якщо не потрібна така семантика, що не підписана. Але врешті-решт реалізація a Subscriberможе спричинити такі пастки, як:

  1. витрачайте ресурси на функціонал, яким ви не будете користуватися
  2. не може успадкувати від іншого класу
  3. написати неправильний код відмови від підписки
  4. скопіювати / вставити код неправильний код або правильний код, написаний для іншого контексту

1
У 2.x Observer використовується для підписки на Observable, а Subscriber - для підписки на Flowable, Абонент більше не реалізує 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 є інтерфейс, що відповідає специфікації реактивних потоків .

Основна відмінність від того Observable, що нові Subscriberпідтримують протитиск.

Observerє передплатою Observableта Subscriberпередплатою Flowable(реалізує org.reactivestreams.Publisher).

Детальний опис дивіться тут .


3

Також у RxJava2 , якщо ви хочете мати можливість скасувати підписку, вам слід використовувати ResourceObserverдля Observableта ResourceSubscriberдля Flowable.

Перевірте це питання

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.