Design Patterns - Observer

Subscribe to newsletter

Surely you’ve seen a website that has newsletters you can subscribe to before.

The goal of newsletter is, instead of having the user visit the website every day, the website sends them a message to notify them that there’s an update. Depending on the website, the message contains either a short summary or the full article.

Subscribing to the newsletters of a website you’re interested in is a good idea because it saves your time: instead of visiting the website every day to check for updates, you only visit the website when you receive a newsletter.

The observer pattern is a pattern in which a list of dependant objects (observers) are notified by the subject when the state held by the subject changes.

The subject contains both the state (what the observers wants to be notified about) and the list of observers (who wants to be notified).

Each observer must register themselves to the subject in order to be notified, similarly to a user that subscribes to a newsletter: unless subscribed, he will not be notified.

Subject

public class Subject {
	
	private List<Observer> observers = new ArrayList<>();
	private int state; 
	
	
	public int getState() {
		return state;
	}
	
	
	public void setState(int state) {
		this.state = state;
		notifyAllObservers(); // every time the state is updated, the observers must be notified 
	}
	
	
	public void registerObserver(Observer observer) {
		observers.add(observer);
	}
	
	
	public void notifyAllObservers() {
		for (Observer observer : observers) {
			observer.update();
		}
	}

}

Observer

An observer can either be an interface or an abstract class, but for the sake of this example, it’ll be an abstract class.

public abstract class Observer {

	protected Subject subject;
	public abstract void update();

}

Concrete Observer

public class SomeObserver extends Observer {
	
	public SomeObserver(Subject subject) {
		this.subject = subject;
		this.subject.registerObserver(this);
	}
	
	
	@Override
	public void update() {
		System.out.println("Subject state has been updated to " + subject.getState());	
	}
	
}

Benefits of the observer pattern

Instead of having multiple classes constantly checking for updates on the same class (subject), the subject notifies the classes that it changed, causing those classes to update only when necessary.

In other words, rather than having the following in every class:

while (true) {
	if (subject.hasChanged()) {
		doSomething();
	}
}

You have the following only present in the subject:

// this is called every time the state held by the subject is updated
for (Observer observer : observers) {
	observer.update();
}