Observer устарел в Java 9. Что мы должны использовать вместо него?


134

Вышла Java 9, и Observerона устарела. Это почему? Значит ли это, что мы больше не должны реализовывать шаблон наблюдателя?

Было бы хорошо узнать, какая альтернатива лучше?

Ответы:


105

Это почему? Означает ли это, что нам больше не следует реализовывать шаблон наблюдателя?

Отвечая на последнюю часть первым -

ДА , это означает, что вам больше не следует внедрятьObserverиObervable.

Почему они устарели -

Они не предоставили достаточно богатой модели событий для приложений. Например, они могли поддерживать только идею о том, что что-то изменилось, но не передавали никакой информации о том, что изменилось.

Ответ Алекса говорит о том, что у Observerнего есть слабость: все Observableодинаковы . Вы должны реализовать логику, которая основана на instanceofи привести объект к конкретному типу в Observable.update()метод.

Чтобы добавить к этому, были ошибки, такие как невозможно сериализоватьObservable класс, потому что он не реализовывал Serializableинтерфейс, и все его члены были частными.

Что является лучшей альтернативой этому?

С другой стороны, у Listenersних много типов, они имеют методы обратного вызова и не требуют приведения. Как указал @Ravi в своем ответе, вы можете использовать PropertyChangeListener вместо этого.

В остальном он @Deprecationбыл отмечен соответствующей документацией для изучения других пакетов, которые также указаны в других ответах.


Обратите внимание, что устаревание также было отмечено анализом, как указано в этом письме -

В наши дни любой, кто сталкивается с ними, вероятно, попадает в них по ошибке при использовании RxJavaили других фреймворков реактивного потока. В этом случае пользователи обычно хотят вместо этого использовать java.util.concurrent.FlowAPI-интерфейсы jdk9, чтобы все платформы реактивных потоков были совместимы / совместимы в рамках своих запланированных будущих версий, совместимых с jdk9.

Изменить : также стоит упомянуть, что отказ от API-интерфейсов вызван не только по вышеуказанной причине, но и невозможностью поддерживать такой устаревший код, как упоминалось в комментариях к нескольким отчетам об ошибках (ссылки выше), которые были повышены до тем или иным способом обозначить улучшение в его реализации.


3
+1. Хороший ответ, хотя я все еще пытаюсь понять это. Является ли Observer в Java устаревшим из-за некоторой внутренней проблемы самого шаблона проектирования (как определено в книге GOF) или проблемы с поддержкой шаблона Java? В других языках OO, таких как C #, C ++, Python, шаблон проектирования наблюдателя также имеет ту же проблему, что и в Java?
Тим

25
Тот факт, что конкретная реализация устарела, не означает, что шаблон Observer имеет фатальные недостатки. Listenerтакже наблюдатель.
chrylis -cautiouslyoptimistic-

@ chrylis Спасибо, не могу не согласиться, одной из основных причин, по которым API устарел, является также сопутствующее ему обслуживание и то, что изменение его реализации могло нарушить другой код.
Наман,

@ curious95 Не могу понять способ уведомления об этом одновременно .
Наман,

4
@ curious95 Да, звонки notifyObservers()происходят одновременно. Вот кодлет из того же ресурса, который подробно объясняет его функции.
Наман,

37

Да, это устарело в Java 9 . И мы больше не можем реализовать шаблон наблюдателя.


Это почему?

Причин больше:

Not Serializable - поскольку Observable не реализует Serializable. Итак, вы не можете сериализовать Observable ни его подкласс.

Нет безопасности потока - методы могут быть переопределены его подклассами, и уведомление о событии может происходить в разных порядках и, возможно, в разных потоках, что достаточно для нарушения любой "безопасности потока".

Меньше предложить -

Они не предоставляют достаточно богатую модель событий для приложений. Например, они поддерживают только идею о том, что что-то изменилось, но не передают никакой информации о том, что изменилось

Открытые проблемы - Как уже упоминалось, было поднято много основных проблем (безопасность потоков, Serializable), и большинство из них имели сложности, которые нужно было исправить, и все еще «не исправлены» или « Нет активной разработки» , и это является причиной, по которой она устарела .

Я также рекомендовал бы прочитать этот ответ. Почему следует исключить шаблон наблюдателя? , @Jeff объяснил другие причины прекращения поддержки.


Итак, какая у нас альтернатива?

Вы можете использовать PropertyChangeEventи PropertyChangeListenerиз java.beansпакета.


PropertyChangeListenerзаменяет Observer, но что я должен расширить / реализовать вместо Observable?
LastStar007

Обновление: я думаю, что подход заключается в добавлении PropertyChangeSupportпеременной экземпляра, но я был бы признателен за подтверждение.
LastStar007

3
@ LastStar007 Я думаю, ты прав. Я нашел пример кода на Baeldung.com, который делает именно это.
Драгос Станчу

14

Почему Observer устарела в Java 9?

Ans:Observable класс и Observerинтерфейс был устаревшим в Java 9 , поскольку модель событий поддерживается Observerи Observableвесьма ограничена, порядок уведомлений доставляетсяObservable не определен, и изменения состояния не в один-на-однозначном соответствии с уведомлениями.

См. Документ Java на https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html.

Альтернатива паттерну наблюдателя?

Существует множество вариантов шаблона проектирования Observer, и Reactive Streams является одним из них.

Реактивные потоки или API потока :

Flowявляется класс введен в Java 9 и имеет 4 взаимосвязанных интерфейсы: Processor, Publisher, SubscriberиSubscription .

Flow.Processor : Компонент, который действует как подписчик и как издатель.

Flow.Publisher : Производитель товаров, полученных подписчиками.

Flow.Subscriber : Получатель сообщений.

Flow.Subscription: Контроль сообщений, связывающий а Flow.Publisherи Flow.Subscriber.

См. Документ Java https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html


8

Учитывая, что Observableкласс и Observerинтерфейс были объявлены устаревшими, начиная с Java 9. Согласно посту Java Observer и Observable устарели в JDK 9

Модель событий, поддерживаемая Observer и Observable, довольно ограничена, порядок уведомлений, доставляемых Observable, не определен, а изменения состояния не находятся в однозначном соответствии с уведомлениями. Для более богатой модели событий рассмотрите возможность использования java.beans пакета. Для надежного и упорядоченного обмена сообщениями между потоками рассмотрите возможность использования одной из параллельных структур данных в java.util.concurrentпакете. Для программирования стиля реактивных потоков см. API потока.


-1

Проблема заключается в глючных реализациях Java класса / интерфейса Java с именами Observer, Observable и т. Д., Но не с шаблоном GoF Observer.


1
почему ответ? На вопрос уже дан подробный ответ с учетом множества различных мнений?
Снорик
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.