观察者和订阅者之间有什么区别?


83

我试图破译以下功能:

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

我从http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/获得了一个很好的rxjava简介,但是它只是顺便提到了Observer,说您将在大多数情况下使用Subscriber从Observable发射到消费项目的时间。

有人可以向我解释

  1. 什么是观察者?
  2. 观察者与订户有何不同?
  3. 上面的代码段是做什么的?

Javadoc使它看起来像订户。订阅者的Javadoc表示它实现了观察者和订阅。我很迷茫。


这是Observer模式vs publish / subscribe。它们是相似的,但有细微的差异。
肖恩·帕特里克·弗洛伊德

4
@SeanPatrickFloyd:您能解释这些差异吗?
user541686 2014年

什么是“详细信息”变量?
玛丽安(MarianPaździoch)2016年

Answers:


63

编辑:@Alrid的评论

tl; dr

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

因此,订阅服务器Observer的实现,在订阅上具有其他语义(更多关于取消订阅)。您问题中的代码只是表明它通过了Observer接口,而不是实现(通常的编程实践)。

此代码还返回a Subscription,这可能是因为该代码的作者认为客户端应该只能访问Subscription方法,而不能访问可观察对象产生的元素。那可能是程序员错误。

很长的故事

确实,您应该阅读此网站(或书籍)的内容:http : //www.introtorx.com 这是有关Rx.Net的,但是概念是相同的,它们是由Erik Meijer创建的,RxJava实现者遵循了它们( (如果适用于Java语言)。

此页面将使您感兴趣(这是第二章):KeyTypes

在这里,您将阅读第一段:

使用Rx时需要了解两种主要类型,以及一些辅助类型的子集,它们可以帮助您更有效地学习Rx。IObserver和IObservable构成了Rx的基本构建块,而ISubject的实现减少了Rx初学者的学习难度。

...

Rx本质上是建立在Observer模式的基础上的。.NET已经公开了实现观察者模式的其他方法,例如多播委托或事件(通常是多播委托)。

即使类型/ API有所不同,您也可以从这本书中学到很多东西,可能比从一些博客中学到的更多。

这是什么不说...因为它是在RxJava实施

RxJava的主要开发人员此时引入了一些细微的变化(请参阅PR #792),从而可以区分两种类型的合同:

  • 通知-> Observer
  • 订阅-> Subscription

这项更改可以更好地表达/分割RxJava库实现类的这些问题。

但是,作为库用户,使用RxJava库的实际实现应该足够好。

实现订户需要更多的知识,工作和维护,实际上,订户的语义非常重要,具体取决于可观察到的源的类型(热还是冷?创建昂贵吗?)


在大多数情况下,公开Subscriber而不是Observer在上述情况下不会干扰代码,但是除非需要那些取消订阅的语义,否则它不是预期的用途。但最终实施Subscriber和可能涉及陷入一些陷阱,例如:

  1. 将资源用于您不会使用的功能
  2. 不能从另一个类继承
  3. 编写不正确的退订代码
  4. 复制/粘贴代码不正确的代码或为其他上下文编写的正确代码

1
在2.x中,Observer用于订阅Observable,而Subscriber用于订阅Flowable
ReactiveX /

39

(编辑:这显然仅适用于RxJava1。)

  1. AnObserver是可以从数据源(Observable)获取数据的对象。数据源通过调用观察者的将数据推送到它onNext()

  2. ASubscriberObserver可以(通过Subscription接口)从该数据源退订。

  3. getCar()函数正在尝试退车,但是没有直接方法可以做到。但是有一个获取汽车详细信息的功能(getCarDetails()),它将调用具有所有汽车详细信息的观察者。因此,它调用该函数并将其传递给观察者,该观察者在获取数据时将从细节中获取汽车数据并将其传递给自己的观察者。


2
从RxJava 2开始,情况并非如此,订户和观察者是两个完全不同的接口。两者都没有扩大
FRR


3

同样在RxJava2中,如果希望能够退订,则应使用ResourceObserverforObservableResourceSubscriberfor Flowable

检查这个问题

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.