Шаблон Observer: уведомление о событиях
Реализуйте Observer, чтобы разделить производителей и потребителей событий в системе отслеживания цен акций.
«Шаблон Observer: уведомление о событиях» — бесплатный урок Java Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Назначение паттерна Observer
Observer, также называемый паттерном «издатель — подписчик», определяет зависимость «один ко многим»: когда состояние Subject изменяется, все зарегистрированные Observer автоматически получают уведомление.
Интерфейсы Subject и Observer
Subject хранит список Observer и уведомляет их. Observer реализует метод update, чтобы реагировать на события.
public interface Observer {
void update(String event, Object data);
}
public interface Subject {
void addObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers(String event, Object data);
}Конкретный Subject: биржевой тикер
Subject хранит состояние и вызывает notifyObservers при каждом изменении состояния. Он управляет списком Observer.
public class StockTicker implements Subject {
private final List<Observer> observers = new ArrayList<>();
private double price;
public void addObserver(Observer o) { observers.add(o); }
public void removeObserver(Observer o) { observers.remove(o); }
public void setPrice(double p) {
this.price = p;
notifyObservers("PRICE_CHANGED", p);
}
public void notifyObservers(String ev, Object data) {
for (Observer o : observers) o.update(ev, data);
}
}Конкретные наблюдатели
Каждый наблюдатель по-своему реагирует на одно и то же уведомление. Добавляйте наблюдателей во время выполнения, не изменяя Subject.
public class AlertSystem implements Observer {
public void update(String ev, Object data) {
if ((double) data < 100) System.out.println("ALERT: Low price!");
}
}
public class Logger implements Observer {
public void update(String ev, Object data) {
System.out.println("LOG: " + ev + " = " + data);
}
}Подключение наблюдателей
Зарегистрируйте наблюдателей в Subject. Все они будут реагировать на его изменения. Отмените регистрацию, чтобы прекратить получать обновления.
StockTicker ticker = new StockTicker();
ticker.addObserver(new AlertSystem());
ticker.addObserver(new Logger());
ticker.setPrice(95.5); // both observers notifiedjava.util.Observable — устарел
В JDK были java.util.Observable и java.util.Observer, но начиная с Java 9 они устарели. Реализуйте собственный механизм или используйте реактивные библиотеки, например RxJava или Project Reactor.
PropertyChangeListener
Компоненты Java предоставляют PropertyChangeSupport — встроенный механизм Observer для изменений свойств компонентов, широко используемый в Swing и JavaFX.
public class Model {
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private int value;
public void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); }
public void setValue(int v) {
int old = this.value; this.value = v;
pcs.firePropertyChange("value", old, v);
}
}Функциональный наблюдатель с потребителем
Используйте Consumer<T> как лёгкий Observer вместо отдельного интерфейса — это идеально подходит для простых обратных вызовов событий.
List<Consumer<Double>> listeners = new ArrayList<>();
listeners.add(p -> { if (p < 100) System.out.println("Low price"); });
listeners.add(p -> System.out.println("Price: " + p));
double newPrice = 95.5;
listeners.forEach(l -> l.accept(newPrice));Observer и шина событий
Шина событий, например Guava EventBus, ещё сильнее отделяет Subject от Observer: Subject отправляет события в шину, не зная, кто их слушает. Observer подписываются с помощью аннотации метода.
// Guava EventBus example
EventBus bus = new EventBus();
bus.register(new Logger()); // subscribe
bus.post(new PriceEvent(95.5)); // publishБезопасность потоков в Observer
Если Observer могут добавляться и удаляться из нескольких потоков, защищайте список с помощью synchronized или используйте CopyOnWriteArrayList при большом количестве уведомлений.
private final List<Observer> observers = new CopyOnWriteArrayList<>();Предотвращение утечек памяти
Сильные ссылки в списке Observer не позволяют сборщику мусора освободить объекты. Используйте WeakReference<Observer> или всегда отменяйте регистрацию Observer, когда они больше не нужны.
Observer в реальных платформах
ApplicationEventPublisher в Spring, LiveData в Android и свойства JavaFX — всё это реализации паттерна Observer на разных уровнях абстракции.
Быстрая проверка
Каково главное преимущество паттерна Observer?
Итоги
Observer определяет цепочку уведомлений «один ко многим». Реализуйте его с помощью интерфейсов или функциональных потребителей. Используйте CopyOnWriteArrayList для безопасности потоков и всегда отменяйте регистрацию Observer, чтобы предотвратить утечки.
Часто задаваемые вопросы
Урок «Шаблон Observer: уведомление о событиях» бесплатный?
Да — полный текст урока «Шаблон Observer: уведомление о событиях» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Шаблон Observer: уведомление о событиях»?
Реализуйте Observer, чтобы разделить производителей и потребителей событий в системе отслеживания цен акций. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Шаблон Observer: уведомление о событиях»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Шаблон Observer: уведомление о событиях
- Шаблон Strategy: взаимозаменяемые алгоритмы
- Шаблон Command: инкапсуляция действий
- Шаблон Template Method: каркасы алгоритмов