Skip to main content

The Observer Pattern

Category: Behavioral

The Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

This pattern is also heavily known as the Publish-Subscribe (Pub/Sub) pattern. It is widely used in event-driven programming, GUI frameworks (like clicking a button), and real-time data streaming applications.


Example: The News Agency​

Imagine a NewsAgency (the Publisher/Subject). When breaking news happens, it needs to instantly notify various NewsChannels (the Subscribers/Observers) so they can broadcast it.

Instead of the News Channels constantly checking the News Agency to ask "Is there new news?" (Polling), the Observer pattern flips it: the News Channels subscribe to the News Agency, and the Agency pushes the news to them only when it happens.

1. The Subject (Publisher) Interface​

The Subject must have methods to attach, detach, and notify observers.

public interface Subject {
void attach(Observer o);
void detach(Observer o);
void notifyObservers();
}

2. The Observer (Subscriber) Interface​

The Observer must have an update() method that the Subject can call.

public interface Observer {
void update(String news);
}

3. The Concrete Subject​

This is the News Agency. It maintains a list of all active subscribers. When its internal state changes (news breaks), it loops through the list and notifies everyone.

import java.util.ArrayList;
import java.util.List;

public class NewsAgency implements Subject {

// The list of subscribers
private List<Observer> channels = new ArrayList<>();

// The internal state
private String breakingNews;

public void setBreakingNews(String news) {
this.breakingNews = news;
notifyObservers(); // Trigger notifications immediately!
}

@Override
public void attach(Observer o) {
channels.add(o);
}

@Override
public void detach(Observer o) {
channels.remove(o);
}

@Override
public void notifyObservers() {
for (Observer channel : channels) {
// Pushing the news to the subscriber
channel.update(this.breakingNews);
}
}
}

4. Concrete Observers​

These are the individual news channels.

public class NewsChannel implements Observer {

private String channelName;

public NewsChannel(String name) {
this.channelName = name;
}

@Override
public void update(String news) {
System.out.println(channelName + " Breaking News Broadcast: " + news);
}
}

5. Client Code​

public class LabObserver1 {

public static void main(String[] args) {
// 1. Create the Publisher
NewsAgency reuters = new NewsAgency();

// 2. Create the Subscribers
NewsChannel cnn = new NewsChannel("CNN");
NewsChannel bbc = new NewsChannel("BBC");

// 3. Subscribe the channels to the agency
reuters.attach(cnn);
reuters.attach(bbc);

// 4. Trigger an event!
System.out.println("--- Reuters sets breaking news ---");
reuters.setBreakingNews("Observer Pattern Discovered!");

// Output:
// --- Reuters sets breaking news ---
// CNN Breaking News Broadcast: Observer Pattern Discovered!
// BBC Breaking News Broadcast: Observer Pattern Discovered!
}
}