在 Java9中不推荐使用观察器。我们应该使用什么来代替它?

Java9出来了,而 Observer已被弃用。 为什么? 这是不是意味着我们不应该再实施观察者模式了?

知道什么是更好的选择会很好吗?

66181 次浏览

考虑到 Observable类和 Observer接口在 Java9时已经被弃用。根据后 JDK9中不推荐使用 Java 的观察器和可观察器

观察者和观察者所支持的事件模型非常有限, 未指定 Obable 传递的通知顺序,并且 状态变化不是与 通知。 对于更丰富的事件模型,可以考虑使用 一个 href = “ https://docs.oracle.com/javase/9/docs/api/java/beans/package-Summary y.html”rel = “ noReferrer”> java.beans 为了在线程之间进行可靠和有序的消息传递,请考虑 中的并发数据结构之一 java.util.concurrent 包。

还有更多原因:

Not Serializable -因为 Observer 不实现 Serializable。

没有线程安全 -方法可以被它的子类覆盖,事件通知可以以不同的顺序发生,可能发生在不同的线程上,这足以破坏任何“线程安全”。

少提供

它们没有为应用程序提供足够丰富的事件模型 例如,它们只支持某些东西已经改变的概念,但是 它们没有传达任何有关已经发生变化的信息

开放问题 -如前所述,有很多主要问题(线程安全性,可串行化) ,其中大多数有复杂的修复,仍然“不固定”或 没有积极发展,这就是为什么它一直是 不赞成的原因。

我也建议读读这个答案 为什么观察者模式应该被废弃?,@Jeff 已经解释了其他不赞成的理由。


那我们还有别的选择吗?

可以使用 一个 href = “ https://docs.oracle.com/javase/9/docs/api/java/beans/package-Summary y.html”rel = “ noReferrer”> java.beans 包中的 一个 href = “ https://docs.oracle.com/javase/9/docs/api/java/beans/PropertyChangeEvent.html”rel = “ noReferrer”> PropertyChangeEvent 一个 href = “ https://docs.oracle.com/javase/9/docs/api/java/beans/PropertyChangeListener.html”rel = “ norefrer”> PropertyChangeListener

为什么? 这是不是意味着我们不应该再实施观察者模式了?

先回答后一部分-

是的,这意味着你不应该再实现 ObserverObervable了。

他们为什么被贬低

它们没有为应用程序提供足够丰富的事件模型。例如,它们只能支持某些事物已经改变的概念,但不能传达任何关于已经改变的信息。

亚历克斯的回答很好地说明了 ABC0有一个弱点: 所有的 Observable都是一样的。您必须实现基于 instanceof的逻辑,并将对象转换为具体类型到 Observable.update()方法中。

除此之外,还有一些类似于 无法序列化 Observable类的 bug,因为它没有实现 Serializable接口,而且它的所有成员都是私有的。

还有什么更好的选择吗?

另一方面,Listeners有很多类型,它们有回调方法,不需要强制转换。正如@Ravi 在他的 回答中指出的,你可以使用 PropertyChangeListener来代替。

对于其余的 @Deprecation已经标记了适当的文档,以探索其他一揽子作为链接在其他答案以及。


请注意,弃用也标记了一个分析,如 这封信-所述

如今,任何人遇到这种情况都可能是因为 在使用 RxJava或其他反应流框架时出现错误 在这种情况下,用户通常希望改用 jdk9 所有反应流框架的 java.util.concurrent.Flow API 应该是兼容的/可互操作的在他们的计划即将到来 兼容 jdk9的版本。

编辑 : 同样值得一提的是,API 的废弃主要不仅仅是因为上面的原因,而且还因为无法维护在一些 bug 报告(链接在上面)的注释中提到的遗留代码,这些报告被提出来以这种或那种方式标志其实现的改进。

为什么在 Java9中不推荐使用观察者?

答: 在 Java 9中,由于 ObserverObservable支持的事件模型非常有限,Observable传递的通知顺序没有指定,而且状态变化与通知没有一对一的对应关系,所以 Observable类和 Observer接口已经被弃用。

请参阅 Java 文档 https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html

替代观察者模式?

观察者设计模式有许多替代方案,Reactive Streams 就是其中之一。

反应流或流 API :

Flow是 Java9中引入的类,有4个相互关联的接口: ProcessorPublisherSubscriberSubscription

Flow.Processor: 同时充当订阅服务器和发布服务器的组件。

Flow.Publisher: 订阅者接收到的项目的生产者。

Flow.Subscriber: 信息接收器。

连接 Flow.PublisherFlow.Subscriber的消息控制。

请参阅 Java 文档 https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html

问题在于 Java 类/接口的实现存在漏洞,比如 Observer、 Observer 等等,但是 GoF 观察者模式没有问题。

也可以使用 CDi 2.0,事件处理