Observer Design Pattern in Java

Observer Pattern is one of the behavioral patterns. Observer design pattern is useful when there is something need to be done with the state of an object and an object wants to get notified whenever there is any change in state. In observer pattern, the object that watches on the state of another object are called Observer and the object that is being watched is called Subject.

This pattern is useful when there is a one-to-many relationship between objects and when an object changes its state, all its dependent objects are notified and updated automatically.

Subject contains a list of observers to notify of any change in its state, so it should provide methods using which observers can register and unregister themselves. Subject also contains a method to notify all observers of any change in state and either it can send the update while notifying the observer or it can provide another method to get the update.

Observer should have a method to set the object to watch and another method that will be used by Subject to notify them of any update.

The definition provided in the original Gang of Four book is given below

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

The real life example of Observer Pattern is we want to publish recruitment status through three different medium such as PostCard, NewsPaper and Internet whenever an update or change occurs in the recruitment status.

The observer pattern is mainly used to implement distributed event handling systems. The Observer pattern is also a key part in the familiar model–view–controller (MVC) architectural pattern.

Class Diagram

Observer Pattern in Java
Implementation

Create an Observer interface which will update the state

package com.roytuts.designpattern.observer;
public interface Observer {
  void update(String message);
}

Create a Subject interface for registering, unregistering and notifying observers

package com.roytuts.designpattern.observer;
public interface Subject {
  void registerObserver(Observer observer);
  void unregisterObserver(Observer observer);
  void notifyObservers();
}

Create a class RecruitmentStatus which implements Subject.

package com.roytuts.designpattern.observer;
import java.util.ArrayList;
import java.util.List;
public class RecruitmentStatus implements Subject {
  private String type;
  private String name;
  private String status;
  private List<Observer> observers = new ArrayList<Observer>();
  public RecruitmentStatus(String type, String name, String status) {
    this.type = type;
    this.name = name;
    this.status = status;
  }
  public String getType() {
    return type;
  }
  public void setType(String type) {
    this.type = type;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getStatus() {
    return status;
  }
  public void setStatus(String status) {
    this.status = status;
    notifyObservers();
  }
  public List<Observer> getObservers() {
    return observers;
  }
  public void setObservers(List<Observer> observers) {
    this.observers = observers;
  }
  @Override
  public void registerObserver(Observer observer) {
    observers.add(observer);
  }
  @Override
  public void unregisterObserver(Observer observer) {
    observers.remove(observer);
  }
  @Override
  public void notifyObservers() {
    for (Observer observer : observers) {
      System.out.println("Notifying observers on change of status of the recruitment procedure");
      observer.update(status);
    }
  }
}

Now we will broadcast the updated status through three different medium such as PostCard, NewsPaper and Internet whenever an update occurs in the status.

package com.roytuts.designpattern.observer;
public class PostCard implements Observer {
  @Override
  public void update(String message) {
    System.out.println("Updated status through Post card : " + message);
  }
}
package com.roytuts.designpattern.observer;
public class NewsPaper implements Observer {
  @Override
  public void update(String message) {
    System.out.println("Updated status through News paper : " + message);
  }
}
package com.roytuts.designpattern.observer;
public class Internet implements Observer {
  @Override
  public void update(String message) {
    System.out.println("Updated status through Internet : " + message);
  }
}

Create a test class for testing the Observer Pattern

package com.roytuts.designpattern.observer;
public class ObserverPatternTest {
  /**
   * @param args
   */
  public static void main(String[] args) {
    Observer newsPaper = new NewsPaper();
    Observer internet = new Internet();
    Observer postCard = new PostCard();
    RecruitmentStatus serviceExam = new RecruitmentStatus("Clerk", "Railway Recruitment", "Exam to be held");
    serviceExam.registerObserver(postCard);
    serviceExam.registerObserver(newsPaper);
    serviceExam.registerObserver(internet);
    serviceExam.setStatus("Face to Face interview date needs to be scheduled");
  }
}

Run the above test class and see the below output in the console

Output 

Notifying observers on change of status of the recruitment procedure
Updated status through Post card : Face to Face interview date needs to be scheduled
Notifying observers on change of status of the recruitment procedure
Updated status through News paper : Face to Face interview date needs to be scheduled
Notifying observers on change of status of the recruitment procedure
Updated status through Internet : Face to Face interview date needs to be scheduled

Usage

If you have an object that needs to share it’s state with others, without knowing who those objects are, the Observer is exactly what you need.

Advantages

The advantage of Observer Pattern is loose coupling between observer and observable objects. The subject only knows the list of observers but it doesn’t care about how observers are implemented. All observers are notified by subject in a single event.

Disadvantages

The disadvantage is debugging becomes very difficult because flow of control is implicitly between observers and observable and if chain of observers found (observers acting as subjects).
Another issue is memory management because subject holds all references of all observers, so if we do not unregister the object it can create the memory issue.

That’s all. Thanks for your reading.

Leave a Reply

Your email address will not be published. Required fields are marked *