StackTips

Observer Design Pattern In Java

Over the course of this article, we will examine yet another heavily used design patterns, the Observer Design Pattern In Java.

The observer design pattern belongs to behavioural family of patterns, that defines a common communication pattern between objects. Observer design pattern defines one-to-many dependency between objects in which one object changes state, all its dependents are notified. Observer design pattern sometimes called as publisher-subscriber design pattern in networked models. Dependent objects are called as observers and the object they are registering to, is called Subject. When subject changes its state, all the observers gets notified.

In this pattern,

  1. Observers register themselves with the subject.
  2. Subject maintains the list of its  dependents (Observers), and it broadcast notification  to all its dependents when it’s state changes.
  3. Observers de-register explicitly when they no more want to be notified.

In order to understand this pattern, let us have a look into some of the real-time examples of observer design pattern

  1. This design pattern is widely used on most of the user interface frameworks
  2. Most commonly used in most of the MVC (Model-View-Controller) models
  3. Consider the different charts in an excel document. A chart is drawn based on the data shown on grid. If there is any change to data in excel grid, the chart is automatically redrawn.

Example

In this example, let us take the case of a news publisher. In typical flow, the new readers subscribe for news. Once a new news is published by publisher, all the observers gets notified. Here the publisher is act as subject and subscribers are observers. A single publisher can have one or many subscribers.

Observer Design Pattern Class Diagram
The above class diagram represents, two observers  Subscriber1 and Subscriber2 register with publisher. Once there is a change in Publisher both the subscribers gets notified.

Observer.java

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

Subscriber1.java

public class Subscriber1 implements Observer {

	@Override
	public void update(String  edition) {
		System.out.println("New Edition from Subscriber1");
	}
}

Subscriber2.java

public class Subscriber2 implements Observer {

	@Override
	public void update(String  edition) {
		System.out.println("New Edition from Subscriber2");
	}
}

Subject.java

public interface Subject {
	public void registerObserver(Observer observer);

	public void removeObserver(Observer observer);

	public void notifyObservers();
}

Publisher.java

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

public class Publisher implements Subject {

	private List<Observer> _observers = new ArrayList<Observer>();

	@Override
	public void registerObserver(Observer observer) {
		System.out.println("Registered observer");		
		_observers.add(observer);
	}

	@Override
	public void removeObserver(Observer observer) {
		System.out.println("Deregister observer");
		_observers.remove(observer);
	}

	@Override
	public void notifyObservers() {
		
		for (Observer observer : _observers) {
			observer.update("Weekly Edition");
		}
	}
}

Test.java

public class Test {

	public static void main(String[] args) {
		
		/* News Publisher */
		Subject publisher = new Publisher();
		
		/* registering observers */
		Observer subscriber1 = new Subscriber1();
		publisher.registerObserver(subscriber1);
		
		Observer subscriber2 = new Subscriber2();
		publisher.registerObserver(subscriber2);
		
		/* Notify observers */
		publisher.notifyObservers();
		
		/* Delete observers */
		publisher.removeObserver(subscriber2);
		
		/* Notify observers */
		publisher.notifyObservers();
	}
}

Output

Registered observer
Registered observer
New Edition from Subscriber1
New Edition from Subscriber2
Deregister observer
New Edition from Subscriber1

Advantages

  1. Provides loose coupling between objects called observer and observable. The subject only know the list of observers it don’t care about their implementation. All the observers are notified by subject in a single message broadcast.
  2. You can add and remove observers at anytime. No modification is need to be done to the subject to add new observers.

Drawbacks

  1. Sometimes if there is a problem, it becomes complex to debug between the chain of observers.
  2. The subject holds reference of all the observers, if we not unregister the object it can cause memory leak. This common problem is called as lapsed listener problem.

Rules of thumb

  1. Explicitly unregister the observers, when no longer it is required to listen to Subject.
  2. It is recommended for subject to hold, weakreference of objects to avoid memory leak.