Implementing a Simple Observer Pattern in Java

A design pattern is a well described approach to solving a software engineering problem. Design patterns are used as a standard approach to solve recurring problems. Design patterns are part of the overall system architecture. This article introduces observer design pattern and a simple implementation using Java – you can as well use any other language of your choice. In the simplest form, observer pattern is a candidate for a situation whereby when one entity changes, multiple other entities need to be updated or at least be aware of the changes.

Based on the above, the independent entity is known as the ‘Observable’ and the entities which need to be updated are the observers. Take an example of your favorite restaurant on a delivering app like Jumia. You want to order food but the restaurant is closed. You provide your email address or phone number to be notified immediately the restaurant opens. In this case, the restaurant is the observable and you are the observer. Another example is whereby a cool website is under construction and you want to be notified when the website goes live. This is the example we are going to use for this article.

We define two interfaces: Observable and Observer. The Observable interface defines three methods: addObserver which takes a parameter of type Observer same as removeObserver and notifyObservers which does not take any parameter. The interface is as follows:

public interface Observable {
	public void addObserver(Observer o);
	public void removeObserver(Observer o);
	public void notifyObservers();
}

On the other hand, the Observer interface has only one method that updates the observers when a change occurs.

public interface Observer {
	public void update();
}

Since we want to be updated when the new website goes live, we create a class NewWebsite which implements Observable. This means this class has to implement the three methods in the Observable interface. The class has an array list of type Observer where it stores all the registered observers (in this case all the users who want to be notified when the website goes live). The variable isLive tracks the status of the website. By default it’s set to false. When the state changes, the method notifyObservers is called which loops through all the registered observers notifying them the website is live. The final code looks like

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

public class NewWebsite implements Observable{
	private List<Observer> users = new ArrayList<Observer>();
	
	private boolean isLive = false;
	
	//Getter for isLive
	public boolean getIsLive() {
		return this.isLive;
	}
	
	//Setter for isLive
	public void setIsLive(boolean isLive) {
		this.isLive = isLive;
		notifyObservers();
	}
	
	@Override
	public void addObserver(Observer o) {
		users.add(o);
	}

	@Override
	public void removeObserver(Observer o) {
		users.remove(o);
		
	}

	@Override
	public void notifyObservers() {
		for(Observer user: users) {
			user.update();
		}
		
	}
	
}

Since the user needs to be updated when the website goes live, the user is an observer. This means the User class will implement Observer interface and implement the update method. The assumption here is probably the user wants to visit the new website when it goes live so we create the method accessWebsite. For simplicity, the method just prints a string. Here is the code for User class

public class User implements Observer{
	private Observable observable = null;
	
	//Constructor
	public User(Observable observable) {
		this.observable = observable;
	}

	@Override
	public void update() {
		accessWebsite();
	}
	
	public void accessWebsite() {
		System.out.println("Accessing new website live ... ");
	}
}

Lastly we create a driver class to test our pattern.

public class DriverClass {
	public static void main(String [] args) {
		Observable obvervable = new NewWebsite();
		
		Observer observer1 = new User(obvervable);
		Observer observer2 = new User(obvervable);
		Observer observer3 = new User(obvervable);
		
		obvervable.addObserver(observer1);
		obvervable.addObserver(observer2);
		obvervable.addObserver(observer3);
		
		obvervable.notifyObservers();
	}
}