Observer Pattern
The Observer pattern is a behavioral design pattern that establishes a one-to-many relationship between objects. It allows multiple objects (observers) to be notified automatically when a change occurs in another object (the subject). This pattern is beneficial when maintaining consistency between related objects without tightly coupling them is important.
The pattern suggests that the Subject maintains a list of all the Observers and notifies them about any changes or updates in the state. To make sure that Subject and Observers are not tightly coupled, every Observer should implement a common Observer Interface. In large applications we can have multiple Subjects to which multiple Observers can be subscribed, hence making a many-to-many relationship.
This pattern is quite similar to a modern Pub/Sub system such as RabbitMQ or Kafka.
Structure
The Observer pattern consists of the following key components:
- Subject: maintains some state and notifies observer about any changes to the state. The subject allows new observers to observe its state and old observers to leave it. Sometimes Subject is also known as Publisher
- Observer: is an interface that defines the method that should be called for any updates to the state of the Subject. Sometimes Observers are also known as Subscribers
- Concrete Observer: are concrete implementations of the Observer interface and react to change in the state of the Subject
When to use the Observer Pattern?
- When you want to make changes to the Observer’s state based on any change to the Subject’s state
- When you want to introduce a new Observer in the future without breaking the existing code (
Open/Closed Principle
)
Implementation Example
The code below demonstrates the Observer design pattern for a simple social media feed example in Java. The SocialMediaFeed
class acts as the subject, maintaining a list of observers (User
objects) and notifying them when a new post is added. The NotificationObserver
interface defines the update
method that concrete observers must implement. The User
class is a concrete observer that receives notifications about new posts. In the main method of the Solution
class, a SocialMediaFeed
is created along with three User
objects. These users are added as observers to the feed. When new posts are added using the addPost
method, all registered users are automatically notified, demonstrating how the Observer pattern allows for loose coupling between the subject (feed) and observers (users), enabling easy broadcast of updates to multiple interested parties.
import java.util.List;
import java.util.ArrayList;
// Client class
public class Solution {
public static void main(String[] args) {
SocialMediaFeed feed = new SocialMediaFeed();
User user1 = new User("Alice");
User user2 = new User("Bob");
User user3 = new User("Charlie");
feed.addObserver(user1);
feed.addObserver(user2);
feed.addObserver(user3);
feed.addPost("David", "Hello, world!");
System.out.println();
feed.addPost("John", "How are you guys?");
}
}
// Subject
class SocialMediaFeed {
private String post;
private String username;
private List<NotificationObserver> observers = new ArrayList<>();
public void addObserver(NotificationObserver observer) {
observers.add(observer);
}
public void removeObserver(NotificationObserver observer) {
observers.remove(observer);
}
public void addPost(String username, String post) {
System.out.println(username + " posted a new post -> (" + post + ")\n");
this.username = username;
this.post = post;
notifyObservers();
}
private void notifyObservers() {
for (NotificationObserver observer : observers) {
observer.update(username, post);
}
}
}
// Observer Interface
interface NotificationObserver {
void update(String username, String post);
}
// Concrete Observer
class User implements NotificationObserver {
private String name;
public User(String name) {
this.name = name;
}
public void update(String username, String post) {
System.out.println(name + " received notification: " + post + " (from " + username + ")");
}
}
The output of the following program will be:
David posted a new post -> (Hello, world!)
Alice received notification: Hello, world! (from David)
Bob received notification: Hello, world! (from David)
Charlie received notification: Hello, world! (from David)
John posted a new post -> (How are you guys?)
Alice received notification: How are you guys? (from John)
Bob received notification: How are you guys? (from John)
Charlie received notification: How are you guys? (from John)
Enjoyed the read? Give it a thumbs up 👍🏻!