Java 9中不推荐使用Observer。


Answers:


104

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

首先回答后一部分-

YES,它意味着你不应该实施ObserverObervableŞ了。

他们为什么被弃用 -

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

亚历克斯(Alex)的回答很好地预言了Observer一个缺点:所有Observable的都是相同的。您必须实现基于的逻辑instanceof并将对象转换为具体类型为Observable.update()方法。

此外,还存在一些错误,例如无法序列化Observable类,因为该类未实现Serializable接口,并且其所有成员都是私有的。

有什么更好的替代方法?

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

对于其余部分,@Deprecation已经标记了适当的文档,以探索与其他答案链接在一起的其他软件包。


请注意,如本邮件中所述,该弃用还标有分析标记 -

如今,遇到这些问题的任何人都可能在使用RxJava或其他反应式流框架时误将它们击中。在这种情况下,用户通常会希望使用jdk9 java.util.concurrent.FlowAPI,因为所有反应流框架都应在计划中的即将与jdk9兼容的版本中兼容/可互操作。

编辑:还值得一提的是,弃用这些API不仅是因为上述原因,而且还无法维护在一些bug报告(上面链接)中提到的遗留代码。以一种或另一种方式标记其实施方面的改进。


3
+1。好的答案,尽管我仍在努力理解。是因为设计模式本身固有的问题(由GOF在书中定义)还是Java支持该模式的问题而弃用Java中的Observer?在其他OO语言(例如C#,C ++,Python)中,观察者设计模式是否也存在与Java中相同的问题?
蒂姆(Tim)

25
不推荐使用特定实现的事实并不意味着Observer 模式存在致命缺陷。Listener还是观察者。
克莱里斯-cautiouslyoptimistic-

@chrylis谢谢,不能同意,不赞成使用该API的主要原因之一还在于它附带的维护功能,并且更改其实现可能会破坏其他代码。
纳曼

@ curious95无法理解那里通知并发的方式
纳曼

4
@ curious95是,调用notifyObservers()是并发的。这是来自同一共享平台的一个小代码,以详细说明其功能。
纳曼

37

是的,在Java 9中已弃用。而且,我们无法再实现观察者模式。


这是为什么?

还有更多原因:

不可序列化 -因为,Observable不实现可序列化。因此,您既不能序列化Observable也不能对其子类进行序列化。

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

少提供 -

它们没有为应用程序提供足够丰富的事件模型。例如,他们仅支持事物已更改的概念,但不传达有关已更改内容的任何信息。

未解决的问题 -如前所述,提出了许多主要问题(线程安全性,可序列化的),并且大多数问题都具有修复的复杂性,但仍然“未修复”或没有活跃的开发,这就是不推荐使用的原因。

我还建议阅读此答案,为什么不建议使用观察者模式?,@ Jeff解释了其他弃用原因。


那么,我们有什么选择?

您可以使用PropertyChangeEventPropertyChangeListenerjava.beans包。


PropertyChangeListener替换Observer,但是我应该代替什么扩展/实现Observable
LastStar007 '18

更新:我认为该方法是将a PropertyChangeSupport作为实例变量添加,但我希望得到确认。
LastStar007 '18

3
@ LastStar007我认为你是对的。我在Baeldung.com上找到了一个代码样本,正是这样做的。
Dragos Stanciu

13

为什么在Java 9中不推荐使用Observer?

答:Observable类和Observer接口都在Java中9遭到反对,因为该事件模型的支持Observer,并Observable是非常有限的,通知被传递的顺序Observable是不确定的,并且状态变化不是一个换一个对应于通知。

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

观察者模式的替代者?

观察者设计模式有多种选择,而响应流就是其中之一。

反应性流或流API

Flow是一类在Java中9中引入并具有4个相互关联的接口:ProcessorPublisherSubscriberSubscription

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

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

Flow.Subscriber :消息的接收者。

Flow.Subscription:消息控件链接a Flow.PublisherFlow.Subscriber

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


7

考虑到从Java 9开始不推荐使用Observable该类和Observer接口。按照该帖子,JDK 9中不推荐使用Java的Observer和Observable。

Observer和Observable支持的事件模型非常有限,Observable传递的通知顺序未指定,并且状态更改与通知不一一对应。对于更丰富的事件模型,请考虑使用该java.beans 程序包。为了在线程之间进行可靠且有序的消息传递,请考虑使用java.util.concurrent程序包中的并发数据结构之一 。有关反应式流样式的编程,请参见Flow API。

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.