It’s a behavioral design pattern, that enables a Subscriber/Observer to register with Observable/Provider/Subject in order to receive notifications whenever the state of the provider/subject changes.

  • Terminology
    • Observable/Provider/Subject - The data source which maintains a collection of subscribers and notifies them.
    • Observer/Subscriber - These are the listeners that’ll get notified by Provider

A known use case for observer pattern is subscribing to blogs or newsletters to get notified whenever a new post is published.

One data source many subscribers.

Here is the UML diagram depicting the scenario.

Observer pattern

Here is an example implementation of Observer design pattern.

public class BlogPost {

  private String author;
  private String title;
  private String content;

  public BlogPost(String author, String title, String content) {
    this.author = author;
    this.title = title;
    this.content = content;
  }

  public String getAuthor() {
    return author;
  }

  public String getTitle() {
    return title;
  }

  public String getContent() {
    return content;
  }

  @Override
  public String toString() {
    return "author=" + getAuthor() + ";" + "title=" + getTitle() + ";" + "content=" + getContent();
  }
}
// Observable/subject/provider
public class Blog {

  private BlogPost blogPost;

  public void addBlogPost(BlogPost blogPost) {
    this.blogPost = blogPost;
    /*
    * Assume the follwing logic in place
    * 1. Call publish blog post
    * 2. Post published confirmation
    */
    notifySubscribers(blogPost);
  }

  private List<Subscriber> subscribers = new ArrayList<>();

  public void addSubsriber(Subscriber subscriber) {
    subscribers.add(subscriber);
  }

  public void removeSubscriber(Subscriber subscriber) {
    subscribers.remove(subscriber);
  }

  private void notifySubscribers(BlogPost blogPost) {
    for (Subscriber subscriber : subscribers) {
      subscriber.update(blogPost);
    }
  }
}
// Observer/Subscriber
public interface Subscriber { 
  void update(Object value);
}
public class Subscriber1 implements Subscriber {

  public void update(Object value) {
    BlogPost blogPost = (BlogPost) value;
    System.out.println("Subscriber1: Received new blog post notification: " + blogPost);
  }
}
public class Subscriber2 implements Subscriber {

  public void update(Object value) {
    BlogPost blogPost = (BlogPost) value;
    System.out.println("Subscriber2: Received new blog post notification: " + blogPost);
  }
}
public class ProgramDriver {

  public static void main(String[] args) {
    // Many subscribers
    Subscriber subscriber1 = new Subscriber1();
    Subscriber subscriber2 = new Subscriber2();

    // One Observable/Provider/Subject/DataSource
    Blog blog = new Blog();
    blog.addSubsriber(subscriber1); // Registers subscriber1
    blog.addSubsriber(subscriber2); // Registers subscriber2

    // Publishing a new BlogPost should notify suscbribers
    BlogPost blogPost = new BlogPost("sairaghavak", "Observer Pattern", "....");
    blog.addBlogPost(blogPost); // This triggers the notification
  }
}

Another way to implement observer pattern using the Java beans API

java.beans.PropertyChangeEvent

java.beans.PropertyChangeListener

java.beans.PropertyChangeSupport

BlogPost - Refer above snippet

// Observable/subject/provider
public class Blog {

  private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);

  public void addPropertyChangeListener(PropertyChangeListener listener) {
    this.pcs.addPropertyChangeListener(listener);
  }

  public void removePropertyChangeListener(PropertyChangeListener listener) {
    this.pcs.removePropertyChangeListener(listener);
  }

  private BlogPost blogPost;

  public void addBlogPost(BlogPost newBlogPost) {
    BlogPost oldBlogPost = this.blogPost;
    this.blogPost = newBlogPost;
    /*
    * Assume the follwing logic in place
    * 1. Call publish blog post
    * 2. Post published confirmation
    */
    this.pcs.firePropertyChange("blogPost", oldBlogPost, blogPost);
  }
}
// Observer: Gets notified when a new post is created
public class Subscriber1 implements PropertyChangeListener {

  @Override
  public void propertyChange(PropertyChangeEvent evt) {
    BlogPost blogPost = (BlogPost) evt.getNewValue();
    System.out.println("Subscriber1: Received new blog post notification: " + blogPost);
  }
}
// Observer: Gets notified when a new post is created
public class Subscriber2 implements PropertyChangeListener {
  @Override
  public void propertyChange(PropertyChangeEvent evt) {
    BlogPost blogPost = (BlogPost) evt.getNewValue();
    System.out.println("Subscriber2: Received new blog post notification: " + blogPost);
  }
}

ProgramDriver - Refer above snippet

Both the approaches to implement this pattern results in same output as shown below

Subscriber1: Received new blog post notification: author=sairaghavak;title=Observer Pattern;content=....
Subscriber2: Received new blog post notification: author=sairaghavak;title=Observer Pattern;content=....

References:

  1. Observer Pattern
  2. Observer design Pattern in .NET
  3. SO thread on Observer Pattern in Java