Observer и Observable в Java: когда и зачем их использовать?

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Следует использовать шаблон Observer для разграничения компонентов: субъект уведомляет наблюдателей о любых изменениях в своем состоянии. C Java 9+ предпочтительнее применять java.beans.PropertyChangeListener и отказаться от устаревших Observer/Observable. Для более сложных задач рекомендуется использование Reactive Streams — в этом контексте основным решением является RxJava.

Пример использования:

Java
Скопировать код
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class DataModel {
    private String data;
    private PropertyChangeSupport pcs = new PropertyChangeSupport(this);

    public void addListener(PropertyChangeListener listener) {
        pcs.addPropertyChangeListener(listener);  // Регистрируем слушателя.
    }
    
    public void setData(String newData) {
        String oldData = this.data;
        this.data = newData;
        pcs.firePropertyChange("data", oldData, newData);  // Осуществляем уведомление слушателей об изменении.
    }
}

// Применение:
DataModel model = new DataModel();
model.addListener((evt) -> System.out.println("Данные обновлены: " + evt.getNewValue()));  // Подписываемся на обновления.
model.setData("UpdatedData");  // Обновляем данные.

Выбор PropertyChangeSupport упрощает реализацию шаблона Observer: аналогично личному ассистенту, он облегчает работу с регистрацией слушателей и информированием их о произошедших изменениях.

Кинга Идем в IT: пошаговый план для смены профессии

Observer и Observable в динамических системах

Динамические системы обеспечивают идеальные условия для применения шаблона Observer, позволяя объектам своевременно реагировать на изменения в состоянии, подобно подписке на обновления в социальных сетях. В событийно-ориентированных архитектурах данный шаблон способствует синхронизации всех компонентов с изменениями в субъекте.

Масштабирование приложений через применение Observer

При масштабировании приложений применение шаблона Observer упрощает реакцию на изменения. Благодаря методам addObserver() и deleteObserver(), можно непринужденно добавлять либо удалять наблюдателей. Это способствует модульности и поддерживаемости кода, а лишь повышает простоту интеграции наблюдателей в глобальную систему.

Реально временные приложения

Примеры из повседневной жизни, включая обновления сервисов или уведомления активных сообществ, ярко демонстрируют эффективность шаблона Observer в контексте распространения обновлений. Опускание флага после оповещения гарантирует актуальность данных, избегая потери или дублирования уведомлений.

Визуализация

Отношение между субъектом и наблюдателями можно уподобить подписке на газету:

Наблюдаемый (📰 Газета):

  • Публикует выпуски с новостями и обновлениями.

Наблюдатель (👀 Подписчик):

  • Подписывается и ожидает новые выпуски.
  • Получает уведомление о выходе нового выпуска.

Структура общения:

  1. 👀 Подписка: Подписчик.присоединяется(Газета)
  2. 📰 Публикация: Газета.публикуетВыпуск()
  3. 👀 Получение уведомления: Подписчик.получаетУведомление()

В реальности:

  • 📰 Газета соответствует Observable
  • 👀 Подписчик — это Observer
  • "Трансляция" информации производится согласно принципам шаблона Observer.

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

Внедрение Observer и Observable

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

Согласованность системы

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

Гибкость уведомлений

Наблюдатели имеют полную свободу действий по отношению к реакции на уведомления: мгновенное реагирование, организация очереди для пакетной обработки или игнорирование некоторых сообщений. Это расширяет сферу применения шаблона, адаптируя его к различным обстоятельствам.

Преимущества и недостатки шаблона Observer

Не следует злоупотреблять использованием шаблона Observer, поскольку избыточные оповещения могут привести к снижению производительности системы. Осуществляйте оповещение только при фактических изменениях, проверьте требуется ли оно через setChanged().

Потокобезопасность

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

Предотвращение утечек памяти

Необходимо следить за утечками памяти. Некорректная отписка наблюдателей может привести к неоправданным затратам памяти. Используйте deleteObserver(), чтобы прекратить связь с ненужными объектами.

Полезные материалы

  1. Observer (Java Platform SE 8) — документация от Oracle по интерфейсу Observer.
  2. Observer Design Pattern in Java | DigitalOcean — подробное руководство по реализации шаблона Observer.
  3. Design Patterns – Observer Pattern — руководство от TutorialsPoint с примерами шаблона Observer.
  4. Observer Design Pattern – GeeksforGeeks — полное введение в шаблон Observer от GeeksforGeeks.
  5. Observable (Java Platform SE 8) — документация Oracle по классу Observable.