This tutorial is part of the Programming Design Concepts tutorial series. If you wish to learn about other design patterns then check it out!

Intent

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

Motivation

The Observer design pattern could quite possibly be the most used design pattern around thanks to the popularity of Model – View – Controller web frameworks such as Laravel and the slightly more mature CodeIgniter to mention but a few. In MVC frameworks you would typically have the View acting as the observer which would observe the Model for any changes, these changes would be typically be carried out using the Controller which is where most of the frameworks functionality would typically lie.

When should you use this pattern?

This pattern is primarily used when you need many objects to receive an update when one object changes. Twitter is a good example, for instance, when you want to follow someone, you essentially add yourself to their follower list and make yourself an Observer of the other persons account, the Observable.

Benefits:

  • Loose coupling from the Observer to the Observable Holds all listeners in a collection that can be accessed through the same interface Easy to add more dependents to list.
  • The subject doesn’t need to know anything about the observers

Negatives

  • The subject may send updates that don’t matter to observers.
  • Observers have no knowledge of each others presence – a simple operation may result in a cascade of updates

Implementation

Below is a java implementation of a basic Subject interface.

public interface Subject {

	public void register(Observer o);
	public void unregister(Observer o);
	public void notifyObserver();

}

Observer – This is an interface through which objects are notified of changes in the subject. Again, the code below showcases an extremely simple Observer interface.

public interface Observer {

	public void update(String postTitle);

}

ConcreteSubject – The concrete implementation of the Subject stores the state and then notifies observers of changes in state. Just for clarity I’ve called this class Blog as the concrete subject which will be observable by our Subscriber observers shown below.

import java.util.ArrayList;

public class Blog implements Subject{

	private ArrayList<observer> observers;
	private String postTitle = "";

	public Blog(){
		observers = new ArrayList<observer>();
	}

	@Override
	public void register(Observer o) {
		// TODO Auto-generated method stub
		observers.add(o);
	}

	@Override
	public void unregister(Observer o) {
		// TODO Auto-generated method stub
		int observerI = observers.indexOf(o);

		System.out.println("Observer " + (observerI+1) + " deleted");

		observers.remove(observerI);
	}

	@Override
	public void notifyObserver() {
		// TODO Auto-generated method stub
		for(Observer o : observers){
			o.update(postTitle);
		}
	}

	public void addNewPost(String title){
		this.postTitle = title;
		notifyObserver();
	}

}

ConcreteObserver – The concrete implementation of the Observer contains a reference to the concrete Subject and it implements the Observer interface to keep state consistent with subject. The Subscriber class which represents our ConcreteObserver below, this keeps a collection of post titles and appends a new post title every time the update function is called by the Blog class. This way we can easily have each subscriber

import java.util.ArrayList;

public class Subscriber implements Observer{

	public ArrayList<string> posts = new ArrayList<>();

	private static int observerIDTracker = 0;

	private int observerID;

	private Subject blog;

	public Subscriber(Subject blog){
		this.blog = blog;

		this.observerID = ++observerIDTracker;

		System.out.println("New Observer " + this.observerID);

		blog.register(this);
	}

	@Override
	public void update(String postTitle) {
		// TODO Auto-generated method stub
		posts.add(postTitle);
		printTitles();
	}

	public void printTitles(){
		System.out.println(posts);
	}

}

Main Class

public class Main {

	public static void main(String[] args){
		Blog blog = new Blog();

		Subscriber sub1 = new Subscriber(blog);
		Subscriber sub2 = new Subscriber(blog);
		Subscriber sub3 = new Subscriber(blog);

		blog.addNewPost("Post 1");
		blog.addNewPost("Post 2");

	}

}

Implementation Issues

As with any design pattern there are several implementation issues that must be considered: http://stackoverflow.com/a/11632412/2903188 – This is an excellent answer that covers all of the important software engineering principles that the Observer pattern breaks in a simple mouseDrag example.