На Java спостерігається застарілий спостерігач 9. Що слід використовувати замість нього?


133

Java 9 вийшла та Observerзастаріла. Чому так? Чи означає це, що ми більше не повинні реалізовувати модель спостерігачів?

Було б добре знати, що є кращою альтернативою?

Відповіді:


104

Чому так? Чи означає це, що ми більше не повинні реалізовувати модель спостерігачів?

Відповідаючи на останню частину першим -

ТАК , це означає, що ви більше не повинні реалізовуватиObserverівиконувати їїObervable.

Чому їх застаріли -

Вони не запропонували достатньо насиченої моделі подій для додатків. Наприклад, вони могли підтримати лише те, що щось змінилося, але не передали жодної інформації про те, що змінилося.

У відповіді Алекса видно, що в Observerнього є слабкість: всі Observables однакові . Вам належить реалізувати логіку, що ґрунтується на instanceofта передати об'єкт конкретному типу в Observable.update()метод.

Щоб додати до нього, були помилки, як один не міг серіалізуватиObservable клас, оскільки він не реалізував Serializableінтерфейс, і всі його члени були приватними.

Яка краща альтернатива цьому?

З іншого боку Listeners, існує маса типів, вони мають методи зворотного виклику і не потребують кастингу. Як вказує @Ravi у своїй відповіді, ви можете скористатися PropertyChangeListener натомість.

Для решти він @Deprecationбув позначений належною документацією для вивчення інших пакетів, як це пов'язано в інших відповідях.


Зауважте, що депресія також була позначена аналізом, зазначеним у цьому листі -

Сьогодні хтось із цими, хто стикається з ними, напевно, потрапляє на них помилково під час використання RxJavaчи інших реактивних потокових рамок. У такому випадку користувачі, як правило, захочуть використовувати java.util.concurrent.FlowAPI jdk9, щоб усі рамки реактивних потоків повинні бути сумісними / сумісними у своїх запланованих майбутніх версіях, сумісних з jdk9.

Редагувати : Варто також зазначити, що припинення API не є головним чином лише з вищезазначеної причини, але також неможливо зберегти такий застарілий код, як згадується в коментарях до кількох звітів про помилки (пов'язані вище), які були порушені відзначити покращення в його здійсненні тим чи іншим способом.


3
+1. Хороша відповідь, хоча я все ще намагаюся зрозуміти це. Чи спостерігається спостереження в Java на чомусь із притаманної проблеми самої схеми дизайну (як визначено у книзі GOF) або через підтримку цього шаблону Java? В інших мовах ОО, таких як C #, C ++, Python, чи модель дизайну спостерігачів також має таку ж проблему, що і в Java?
Тім

25
Той факт , що конкретна реалізація є застарілим , не означає , що спостерігач шаблон смертельно зіпсований. Listenerє також Спостерігачем.
chrylis -обережнооптимістично-

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

@ curious95 Не в змозі зрозуміти спосіб повідомлення про одночасне існування.
Наман

4
@ цікаво95 Так, дзвінки notifyObservers()одночасні. Ось кодлет із того самого спільного, щоб детально пояснити його функціональність.
Наман

37

Так, це застаріло в Java 9 . І ми більше не можемо реалізувати схему спостерігачів.


Чому так?

Є більше причин:

Не серіалізується - оскільки, спостерігається не реалізує серіалізабельність. Отже, ви не можете серіалізувати спостерігається ні його підклас.

Без безпеки потоку - Методи можуть бути замінені її підкласами, а сповіщення про події може відбуватися в різних порядках і, можливо, в різних потоках, що достатньо, щоб порушити будь-яку "безпеку потоку".

Менше пропозицій -

Вони не забезпечують достатньо багату модель подій для додатків. Наприклад, вони підтримують лише те, що щось змінилося, але вони не передають жодної інформації про те, що змінилося

Відкриті проблеми - Як уже згадувалося, було порушено безліч основних питань (безпека потоку, Serializable), і більшість із них мали складності виправити і досі «не виправлено» або немає активного розвитку , і саме тому це було застаріло .

Я також рекомендував би прочитати цю відповідь Чому слід спостерігати за тим, щоб модель спостерігачів була застарілою? , @Jeff пояснив інші причини знецінення.


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

Можна використовувати PropertyChangeEventі PropertyChangeListenerз java.beansпакета.


PropertyChangeListenerзамінює Observer, але що мені слід розширити / впровадити замість Observable?
LastStar007

Оновлення: Я думаю, що підхід полягає в тому, щоб додати PropertyChangeSupportзмінну екземпляра, але я вдячний підтвердження.
LastStar007

3
@ LastStar007 Я думаю, ти маєш рацію. Я знайшов зразок коду на Baeldung.com, який робить саме це.
Драгос Станцю

13

Чому Observer застарілий у Java 9?

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

Дивіться сторінку Java doc https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html

Альтернатива шаблону спостерігача?

Існує багато альтернатив структури дизайну Observer, і Реактивні потоки є однією з них.

API реактивних потоків або потоку :

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

Flow.Processor : Компонент, який виступає і передплатником, і видавцем.

Flow.Publisher : Виробник предметів, отриманих Абонентами.

Flow.Subscriber : Приймач повідомлень.

Flow.Subscription: Управління повідомленнями, що посилаються на a Flow.Publisherі Flow.Subscriber.

Дивіться сторінку Java doc https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html


7

Беручи до уваги, що Observableклас та Observerінтерфейс застаріли, як у Java 9. Відповідно до повідомлення спостерігач і спостережуване Java застаріли в JDK 9

Модель подій, що підтримується Observer та Observable, досить обмежена, порядок повідомлень, доставлених Observable, не визначений, а зміни стану не входять у відповідність один одному на один із повідомленнями. Для багатшої моделі подій розгляньте можливість використання java.beans пакету. Для надійного та упорядкованого обміну повідомленнями між потоками розгляньте використання однієї з одночасних структур даних у java.util.concurrentпакеті. Інформацію про програмування стилів реактивних потоків див. API Flow.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.