Observer ist in Java 9 veraltet. Was sollten wir stattdessen verwenden?

133

Java 9 wurde veröffentlicht und Observerist veraltet. Warum ist das so? Bedeutet das, dass wir kein Beobachtermuster mehr implementieren sollten?

Es wäre gut zu wissen, was eine bessere Alternative ist.

neugierig95
quelle

Antworten:

104

Warum ist das so? Bedeutet das, dass wir kein Beobachtermuster mehr implementieren sollten?

Den letzten Teil zuerst beantworten -

JA , es bedeutet, dass Sie nicht mehr implementieren solltenObserverundObervables.

Warum wurden sie veraltet -

Sie lieferten kein ausreichend umfangreiches Ereignismodell für Anwendungen. Zum Beispiel könnten sie nur die Vorstellung unterstützen, dass sich etwas geändert hat, aber keine Informationen darüber vermitteln, was sich geändert hat.

Alex 'Antwort bringt es auf den Punkt, dass Observeres eine Schwäche hat: Alle Observablesind gleich . Sie müssen die Logik, die auf instanceofeinem konkreten Typ basiert, implementieren und in eine Observable.update()Methode umwandeln.

Hinzu kam, dass es Fehler gab, als könnte man dieObservable Klasse nicht serialisieren , da sie keine SerializableSchnittstelle implementierte und alle Mitglieder privat waren.

Was ist eine bessere Alternative dazu?

Auf der anderen Seite Listenersgibt es viele Typen und sie haben Rückrufmethoden und erfordern kein Casting. Wie @Ravi in ​​seiner Antwort angedeutet hat, können Sie davon Gebrauch machen PropertyChangeListener stattdessen davon .

Für den Rest @Deprecationwurde das mit der richtigen Dokumentation markiert, um andere Pakete zu untersuchen, die auch in anderen Antworten verlinkt sind.


Beachten Sie, dass die Abschreibung auch mit einer Analyse markiert wurde, wie in dieser Mail angegeben -

Heutzutage trifft jeder, der auf diese stößt, sie wahrscheinlich versehentlich, während er RxJavaandere Reactive-Stream-Frameworks verwendet. In diesem Fall möchten Benutzer normalerweise stattdessen die jdk9- java.util.concurrent.FlowAPIs verwenden, damit alle Reactive -Streams-Frameworks innerhalb ihrer geplanten kommenden jdk9-kompatiblen Versionen kompatibel / interoperabel sind.

Bearbeiten : Es ist auch erwähnenswert, dass die Ablehnung der APIs nicht in erster Linie auf den oben genannten Grund zurückzuführen ist, sondern auch darauf, dass der in den Kommentaren einiger der oben verlinkten Fehlerberichte erwähnte Fehlercode nicht beibehalten werden kann Markieren Sie eine Verbesserung der Implementierung auf die eine oder andere Weise.

Naman
quelle
3
+1. Gute Antwort, obwohl ich immer noch versuche, es zu verstehen. Ist Observer in Java aufgrund eines inhärenten Problems des Entwurfsmusters selbst (wie im Buch von GOF definiert) oder des Problems der Unterstützung des Musters durch Java veraltet? Hat das Beobachter-Entwurfsmuster in anderen OO-Sprachen wie C #, C ++, Python das gleiche Problem wie in Java?
Tim
25
Die Tatsache, dass eine bestimmte Implementierung veraltet ist, bedeutet nicht, dass das Observer- Muster fatal fehlerhaft ist. Listenerist auch ein Beobachter.
Chrylis
@chrylis Danke, ich kann nicht mehr zustimmen. Einer der Hauptgründe für die Ablehnung der API ist auch die damit verbundene Wartung, und dass eine Änderung der Implementierung möglicherweise anderen Code beschädigt hat.
Naman
@ neugier95 Kann die Art der gleichzeitigen Benachrichtigung dort nicht verstehen .
Naman
4
@ neugierig95 Ja, es notifyObservers()wird gleichzeitig angerufen . Hier ist ein Codelet aus demselben, um seine Funktionalität im Detail zu erklären.
Naman
37

Ja, es ist in Java 9 veraltet . Und wir können kein Beobachtermuster mehr implementieren.


Warum ist das so?

Es gibt weitere Gründe:

Nicht serialisierbar - Da Observable Serializable nicht implementiert. Sie können also weder Observable noch seine Unterklasse serialisieren.

Keine Thread-Sicherheit - Die Methoden können von ihren Unterklassen überschrieben werden, und Ereignisbenachrichtigungen können in unterschiedlichen Reihenfolgen und möglicherweise in unterschiedlichen Threads auftreten, was ausreicht, um die "Thread-Sicherheit" zu stören.

Weniger zu bieten -

Sie bieten kein ausreichend umfangreiches Ereignismodell für Anwendungen. Zum Beispiel unterstützen sie nur die Vorstellung, dass sich etwas geändert hat, aber sie vermitteln keine Informationen darüber, was sich geändert hat

Offene Probleme - Wie bereits erwähnt, wurden viele wichtige Probleme angesprochen (Thread-Sicherheit, serialisierbar), und die meisten von ihnen mussten komplex behoben werden und waren immer noch "nicht behoben" oder keine aktive Entwicklung . Dies ist der Grund, warum sie veraltet sind .

Ich würde auch empfehlen, diese Antwort zu lesen. Warum sollte das Beobachtermuster veraltet sein? , @Jeff hat andere Gründe für die Ablehnung erklärt.


Also, was ist die Alternative, die wir haben?

Sie können PropertyChangeEventund PropertyChangeListeneraus java.beansPaket verwenden.

Ravi
quelle
PropertyChangeListenerersetzt Observer, aber was soll ich anstelle von erweitern / implementieren Observable?
LastStar007
Update: Ich denke, der Ansatz besteht darin, eine PropertyChangeSupportals Instanzvariable hinzuzufügen , aber ich würde mich über eine Bestätigung freuen.
LastStar007
3
@ LastStar007 Ich denke du hast recht. Ich habe auf Baeldung.com ein Codebeispiel gefunden , das genau das tut.
Dragos Stanciu
13

Warum ist Observer in Java 9 veraltet?

Antwort: Die ObservableKlasse und die ObserverSchnittstelle sind in Java 9 veraltet, da das von Observerund unterstützte Ereignismodell Observablesehr begrenzt ist, die Reihenfolge der von gelieferten Benachrichtigungen Observablenicht angegeben ist und Statusänderungen nicht eins zu eins mit Benachrichtigungen übereinstimmen.

Siehe Java-Dokument https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html

Alternative des Beobachtermusters?

Es gibt viele Alternativen zum Observer-Entwurfsmuster, und Reactive Streams ist eine davon.

Reaktive Streams oder Flow-API :

Floweine Klasse in Java 9 und verfügt über 4 miteinander verbundenen Schnittstellen eingeführt: Processor, Publisher, Subscriberund Subscription.

Flow.Processor : Eine Komponente, die sowohl als Abonnent als auch als Herausgeber fungiert.

Flow.Publisher : Ein Hersteller von Artikeln, die Abonnenten erhalten haben.

Flow.Subscriber : Ein Empfänger von Nachrichten.

Flow.Subscription: Nachrichtensteuerung, die ein Flow.Publisherund verbindet Flow.Subscriber.

Siehe Java-Dokument https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html

Mohit Tyagi
quelle
7

In Anbetracht dessen, dass die ObservableKlasse und die ObserverSchnittstelle ab Java 9 veraltet sind. Gemäß dem Beitrag sind Javas Observer und Observable in JDK 9 veraltet

Das von Observer und Observable unterstützte Ereignismodell ist recht begrenzt, die Reihenfolge der von Observable gelieferten Benachrichtigungen ist nicht angegeben, und Statusänderungen stehen nicht im Einklang mit Benachrichtigungen. Verwenden Sie für ein umfassenderes Ereignismodell das java.beans Paket. Verwenden Sie für zuverlässiges und geordnetes Messaging zwischen Threads eine der gleichzeitigen Datenstrukturen im java.util.concurrentPaket. Informationen zur Programmierung im Stil reaktiver Streams finden Sie in der Flow-API.

Ousmane D.
quelle