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
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.
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 with practical examples. Add new operations to object structures without modifying existing classes 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.