The Observer Pattern
The Observer Pattern
The Observer Pattern establishes a one-to-many dependency between objects so that when one object (the subject) changes state, all its dependants (observers) are notified and updated automatically. This is the foundation of event-driven programming and is used extensively in GUIs, message queues, and reactive systems.
Why Observer Matters
Suppose you run a newsletter platform. When a new article is published, subscribers must be notified by email, push notification, and in-app alert. Without Observer the publisher would need to know about every notification channel and call each one directly. With Observer each channel registers as a listener, and the publisher simply notifies all registered observers without caring how they work.
Class Diagram
+-------------------+
| Subject |
+-------------------+
| - observers[] |
| - title |
+-------------------+
| + register(o) |
| + unregister(o) |
| + notifyAll() |
| + setTitle(t) |
+---------+---------+
|
| notifies
|
+---------+---------+
| Observer | <<interface>>
+-------------------+
| + update(title) |
+---------+---------+
|
+----------+----------+
| | |
+--+------+ +--+------+ +--+--------+
| Email | | Push | | InApp |
| Notif. | | Notif. | | Notif. |
+--------+ +--------+ +-----------+
Code Example
Define the Observer interface and the Subject class that manages subscriptions:
public interface Observer {
void update(String title);
}
public class Newsletter {
private List<Observer> observers = new ArrayList<>();
private String title;
public void register(Observer o) { observers.add(o); }
public void unregister(Observer o) { observers.remove(o); }
public void setTitle(String title) {
this.title = title;
notifyAllObservers();
}
private void notifyAllObservers() {
for (Observer o : observers) {
o.update(title);
}
}
}
Implement concrete observers for different notification channels:
public class EmailNotifier implements Observer {
public void update(String title) {
System.out.println("Email alert: " + title + " published!");
}
}
public class PushNotifier implements Observer {
public void update(String title) {
System.out.println("Push notification: " + title);
}
}
// Usage
Newsletter blog = new Newsletter();
blog.register(new EmailNotifier());
blog.register(new PushNotifier());
blog.setTitle("Design Patterns Explained");
Publish/Subscribe in Java
The standard java.util.Observer interface was deprecated in Java 9 because its design had flaws - the Observable class was concrete, preventing reuse. Modern frameworks like Spring provide the ApplicationEventPublisher and @EventListener annotation to implement pub/sub cleanly. The principle is identical but the API is more flexible.
Real-World Use
GUI button clicks fire ActionListener callbacks. Chat applications broadcast messages to all connected clients. Stock tickers push price updates to every subscriber. The Observer Pattern is everywhere once you start looking for it.
Key Points
- The subject maintains a list of observers and notifies them on state change.
- Observers are loosely coupled to the subject - the subject does not know their concrete types.
- Registration and unregistration happen dynamically at runtime.
- Circular notifications (observer triggers subject) must be handled carefully.
- Modern Java replaces the deprecated Observer with event-driven frameworks.