Learnitweb

Observer Pattern – Java

1. Introduction

According to GoF definition, Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
Observer pattern is a behavioral design pattern. In this design pattern there is a subject to which observers subscribe. Whenever the state of subject changes, all its observers are notified automatically about the change. This design pattern creates a one-to-many dependency between subject and its observers.

Observers have the facility to register and unregister themselves to the subject. This model is also referred as Publish-Subscriber model.

2. Real-life example

In real-life we subscribe to magazines, newspapers and notifications in mobile applications. Whenever a new issue of magazine is published, we receive the latest issue. Whenever we loose interest in that magazine or don’t want to further read the magazine, we can unregister ourselves.

Another real-life example of receiving notifications from mobile applications like Facebook, Whatsapp, Twitter and so on.

3. Programming world example

  • Observer pattern is the basis of message oriented applications. Frameworks like JMS are based on this pattern.
  • In UI programming, various events are handled by listener objects. Whenever an event happens, like click of button, the listener function is triggered. All these mechanisms use observer pattern.

4. Example

In this example, we’ll create two observers and a subject. These two observers will register to the subject. We’ll then update the subject value and observe that the observers are notified. We’ll then unregister one observer and verify that only one observer is notified.

4.1 Implementation

IObserver.java

package com.learnitweb;

public interface IObserver {
	void update(int i);
}

ISubject.java

package com.learnitweb;

public interface ISubject {
	void register(IObserver o);

	void unregister(IObserver o);

	void notifyObservers(int i);
}

Observer1.java

package com.learnitweb;

public class Observer1 implements IObserver {
	@Override
	public void update(int i) {
		System.out.println("Observer1 updated value: " + i);
	}
}

Observer2.java

package com.learnitweb;

public class Observer2 implements IObserver {
	@Override
	public void update(int i) {
		System.out.println("Observer2 updated value: " + i);
	}
}

Subject.java

package com.learnitweb;

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

public class Subject implements ISubject {
	List<IObserver> observersList = new ArrayList<IObserver>();

	private int subjectValue;

	public List<IObserver> getObserversList() {
		return observersList;
	}

	public void setObserversList(List<IObserver> observersList) {
		this.observersList = observersList;
	}

	public int getSubjectValue() {
		return subjectValue;
	}

	public void setSubjectValue(int subjectValue) {
		this.subjectValue = subjectValue;
		// Notify observers for the value change
		notifyObservers(subjectValue);
	}

	@Override
	public void register(IObserver o) {
		observersList.add(o);
	}

	@Override
	public void unregister(IObserver o) {
		observersList.remove(o);
	}

	@Override
	public void notifyObservers(int updatedValue) {
		for (int i = 0; i < observersList.size(); i++) {
			observersList.get(i).update(updatedValue);
		}
	}
}

ObserverPatternExecutor.java

package com.learnitweb;

public class ObserverPatternExecutor {
	public static void main(String[] args) {
		Subject sub = new Subject();

		Observer1 observer1 = new Observer1();
		Observer2 observer2 = new Observer2();

		System.out.println("Registering observers....");
		sub.register(observer1);
		sub.register(observer2);
		System.out.println("Number of observers registered: " + sub.getObserversList().size());

		System.out.println("Changing value of subject.Observers will be notified.");
		sub.setSubjectValue(10);

		System.out.println("Changing value of subject again.Observers will be notified.");
		sub.setSubjectValue(20);

		// unregister observer1 only
		sub.unregister(observer1);
		System.out.println("One observer unregistered.");

		System.out.println("Changing value of subject again.Observers will be notified.");
		// Now only observer2 will observe the change
		sub.setSubjectValue(100);
	}
}

Output

Registering observers....
Number of observers registered: 2
Changing value of subject.Observers will be notified.
Observer1 updated value: 10
Observer2 updated value: 10
Changing value of subject again.Observers will be notified.
Observer1 updated value: 20
Observer2 updated value: 20
One observer unregistered.
Changing value of subject again.Observers will be notified.
Observer2 updated value: 100