Java 3 min read

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.

MR

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 🔔

  1. Channel (Subject): Uploads a video.
  2. Subscriber (Observer): Gets a notification.
  3. You (Subscriber) don’t check the channel every second. The Channel notifies you.

Visualizing the Pattern

Observer 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

FeatureDetails
CategoryBehavioral
Problem SolvedPolling, Tight coupling between events and listeners
Key implementationList<Observer> in Subject, loop to notify()
ProsOpen/Closed Principle (Add new listeners without changing Subject logic)
ConsMemory 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 unsubscribe or use WeakReferences if listeners have shorter lifecycles than subjects.

Advertisement

MR

Moshiour Rahman

Software Architect & AI Engineer

Share:
MR

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

Comments

Comments are powered by GitHub Discussions.

Configure Giscus at giscus.app to enable comments.