The Observer Design Pattern: Don't Call Us, We'll Call You
Master the Observer Pattern in Java. Learn how to implement event-driven architectures and decouple data sources from listeners.
Moshiour Rahman
Advertisement
The Problem: Polling is Expensive
Imagine you are waiting for a package delivery.
- Bad Approach (Polling): You call the post office every 5 minutes. “Is it here yet?” “No.” “Is it here yet?” “No.”
- Wastes your time.
- Wastes the post office’s time.
In code, this looks like a while(true) loop checking for status updates. It burns CPU cycles and latency is high.
The Solution: The Observer Pattern
The Observer Pattern defines a subscription mechanism to notify multiple objects about any events that happen to the object they’re observing.
Real-Life Analogy: YouTube Subscriptions 🔔
- Channel (Subject): Uploads a video.
- Subscriber (Observer): Gets a notification.
- You (Subscriber) don’t check the channel every second. The Channel notifies you.
Visualizing the Pattern

Implementation
1. The Observer Interface
public interface Observer {
void update(String videoTitle);
}
2. The Subject Interface
public interface Subject {
void subscribe(Observer o);
void unsubscribe(Observer o);
void notifyObservers(String videoTitle);
}
3. Concrete Subject (The YouTuber)
import java.util.ArrayList;
import java.util.List;
public class YouTubeChannel implements Subject {
private List<Observer> subscribers = new ArrayList<>();
private String channelName;
public YouTubeChannel(String channelName) {
this.channelName = channelName;
}
@Override
public void subscribe(Observer o) {
subscribers.add(o);
}
@Override
public void unsubscribe(Observer o) {
subscribers.remove(o);
}
@Override
public void notifyObservers(String videoTitle) {
for (Observer o : subscribers) {
o.update(videoTitle);
}
}
public void uploadVideo(String title) {
System.out.println(channelName + " uploaded: " + title);
notifyObservers(title);
}
}
4. Concrete Observer (The Fan)
public class Subscriber implements Observer {
private String name;
public Subscriber(String name) {
this.name = name;
}
@Override
public void update(String videoTitle) {
System.out.println("Hey " + name + "! New video uploaded: " + videoTitle);
}
}
Usage
YouTubeChannel techyOwls = new YouTubeChannel("TechyOwls");
Subscriber alice = new Subscriber("Alice");
Subscriber bob = new Subscriber("Bob");
techyOwls.subscribe(alice);
techyOwls.subscribe(bob);
// Action occurs...
techyOwls.uploadVideo("Java Design Patterns");
// Output:
// Hey Alice! New video uploaded: Java Design Patterns
// Hey Bob! New video uploaded: Java Design Patterns
techyOwls.unsubscribe(bob); // Bob unfollows
techyOwls.uploadVideo("Advanced AI");
// Output:
// Hey Alice! New video uploaded: Advanced AI
In The Wild (Real World Examples)
1. java.util.EventListener (Swing/AWT)
All UI button clicks are Observer patterns.
button.addActionListener(listener) is effectively subject.subscribe(observer).
2. Spring ApplicationEvent
Spring’s Event mechanism (ApplicationEventPublisher and @EventListener) is a decoupled Observer implementation.
Cheat Sheet
| Feature | Details |
|---|---|
| Category | Behavioral |
| Problem Solved | Polling, Tight coupling between events and listeners |
| Key implementation | List<Observer> in Subject, loop to notify() |
| Pros | Open/Closed Principle (Add new listeners without changing Subject logic) |
| Cons | Memory Leaks (Lapsed Listener Problem: If you forget to unsubscribe, objects stay in memory) |
Tips to Remember 🧠
- “Subscription”: Whenever you hear “subscribe/publish” or “listen”, it’s Observer.
- Memory Leaks: Always implement
unsubscribeor use WeakReferences if listeners have shorter lifecycles than subjects.
Advertisement
Moshiour Rahman
Software Architect & AI Engineer
Enterprise software architect with deep expertise in financial systems, distributed architecture, and AI-powered applications. Building large-scale systems at Fortune 500 companies. Specializing in LLM orchestration, multi-agent systems, and cloud-native solutions. I share battle-tested patterns from real enterprise projects.
Related Articles
The Visitor Design Pattern: Add Operations Without Modifying Classes
Master the Visitor Pattern in Java. Learn how to add new operations to object structures using double dispatch.
JavaThe Mediator Design Pattern: Centralize Complex Communications
Master the Mediator Pattern in Java. Learn how to reduce coupling by having objects communicate through a mediator instead of directly.
JavaThe Command Design Pattern: Turning Actions into Objects
Master the Command Pattern in Java. Learn how to encapsulate requests as objects to enable Undo/Redo, queuing, and macro commands.
Comments
Comments are powered by GitHub Discussions.
Configure Giscus at giscus.app to enable comments.