Observer Pattern Design Patterns in Java

The observer pattern is one of the behavioral patterns. The observer pattern defines an object which is called, subject. The subject object is responsible for maintaining a list of the objects, which depend on it. These objects are known as observers. Whenever a change of state occurs in a system, the subject object notifies observers about it. To notify the observers, the subject object calls one of their methods.

This pattern is used in implementing a distributed event handling systems, mostly in, event-driven software. The modern languages like C# and Java, they have built-in event constructs. These built-in features help in implementing the observer pattern components. The advantage of that is ease of programming and implementation of short codes. In modern-view-controller (MVC) architectural pattern, the observer pattern is a key part. In various different programming libraries and systems, the observer pattern is implemented.

Observer Pattern

According to the Gang of Four:

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

For example, facebook post comments is one of the example of the observer design pattern, if comment to the post of your friend, then you always notified by this post whenever any comment on same post again. The Figure below illustrates the Observer pattern.

Observer Design Pattern

To design, versatile and reusable object-oriented software, there is 23 well-known Gang of Four (GoF) design patterns, the observer pattern is one of them. There are several problems that the observer pattern cater. The need is to define a one-to-many dependency between object without having to make the objects tightly linked or coupled. To ensure that when an object in the system changes its state, the other objects, which are dependent, are notified automatically.

One of the dependent objects is supposed to be able to update an open-ended number of different other objects. To define a one-to-many dependency between objects using one single, defined object (subject- which is responsible to notify others the state of dependent objects directly), it creates inflexibility, because it tightly couples the subject object to certain dependent objects. The objects which are tightly linked together, it is difficult to implement, test, change and reuse them, because these objects hold information about and know how to update many different objects, which are linked to it. The observer pattern defines the Subject and Observer objects because the observer pattern is used to automatically notify other dependent objects about the change in state of the subject object.

Spring 5 Design Pattern Book

You could purchase my Spring 5 book that is with title name “Spring 5 Design Patterns“. This book is available on the Amazon and Packt publisher website. Learn various design patterns and best practices in Spring 5 and use them to solve common design problems. You could use author discount to purchase this book by using code- “AUTHDIS40“.
Spring-5-Design-Pattern

The subject is responsible for maintaining a list of Observers and notifying them about the state changes by calling update() function. The observers are responsible for registering and unregistering themselves on the subject object. This is done to be able to get notified when a change of state occurs, and to be able to update their state when they are notified. With this approach, the subject and observers are now loosely coupled. They have no direct information of a link to each other. It is now possible to add or remove the observers independently.

The notification-registration communication is also known as publish-subscribe. The problem is observer behavioral pattern is that is able to cause memory leaks, which is also called, lapsed listener problem. This occurs because in the observer pattern’s basic implementation, the explicit registration and deregistration, both are required because of the subject object stores a strong reference to the observers, which keep them running. The memory leaks can be prevented from happening, if the references, stored in the subject change to weak references.

Benefits of the Observer Pattern

There are following lists of the benefits of using the Observer pattern:

  • This pattern provides decoupled relationship between the subject and observer
  • It provides support for broadcasting.

UML Class Diagram for This Pattern

Let’s see the following UML diagram is showing the all components of Observer design pattern:

Observer Pattern Design Patterns in Java
Subject
It is an interface. It knows its observers.
ConcreteSubject
It is a concrete implementation of Subject, it has information about all its observers to be notifed when its state changes.
Observer
It is an interfac to be notified of changes in a subject.
ConcreteObserver
It is a concrete implementation of Observer, it keep its state consistent with the subject’s state.

Observer Pattern Implementation Example

Observer design pattern is also called as publish-subscribe pattern. Some of it’s implementations are;

  • java.util.EventListener in Swing
  • javax.servlet.http.HttpSessionBindingListener
  • javax.servlet.http.HttpSessionAttributeListener

Step 1: Create Subject.
Subject.java

/**
 * 
 */
package com.dineshonjava.observer.pattern;

/**
 * @author Dinesh.Rajput
 *
 */
public interface Subject {
	
	//methods to register user as an facebook friend observers
	public void registerAsAFriend(Observer friendRequest);
	
	//methods to unregister user from facebook friend observers
	public void unregisterFromFriend(Observer removeFriend);
	
	//method to notify observers i.e. facebook friends of change
	public void notifyFacebookFriends();
	
	//method to get updates from subject
	public Object getUpdate(Observer obj);
	
}

Step 2: Create Observer.
Observer.java

/**
 * 
 */
package com.dineshonjava.observer.pattern;

/**
 * @author Dinesh.Rajput
 *
 */
public interface Observer {
	
	public void update();
		
	public void setSubject(Subject sub);
}

Step 3: Create concrete subject class.
FacebookPost.java

package com.dineshonjava.observer.pattern;

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

/**
 * @author Dinesh.Rajput
 *
 */
public class FacebookPost implements Subject {
	
	private List observers = new ArrayList();
	private String comment;

	@Override
	public void registerAsAFriend(Observer friendRequest) {
		observers.add(friendRequest);	
	}

	@Override
	public void unregisterFromFriend(Observer removeFriend) {
		observers.remove(removeFriend);	
	}

	@Override
	public void notifyFacebookFriends() {
		for (Observer observer : observers) {
			observer.update();
		}
	}

	@Override
	public Object getUpdate(Observer obj) {
		return this.comment;
	}
	
	//method to post message to the topic
	public void postComment(String comment){
		System.out.println("Comment Posted to Post: "+comment);
		this.comment=comment;
		notifyFacebookFriends();
	}

}

Step 4: Create concrete observer class.
FacebookPost.java

/**
 * 
 */
package com.dineshonjava.observer.pattern;

/**
 * @author Dinesh.Rajput
 *
 */
public class FacebookFriend implements Observer {
	
	private String friendName;
	private Subject facebookPost;
	
	public FacebookFriend(String friendName){
		this.friendName = friendName;
	}

	@Override
	public void update() {
		String comment = (String) facebookPost.getUpdate(this);
		if(comment == null){
			System.out.println(friendName+":: No new comment");
		}else{
			System.out.println(friendName+":: New comment::"+comment);
		}
	}

	@Override
	public void setSubject(Subject facebookPost) {
		this.facebookPost = facebookPost;
	}

}

Step 5: Use Subject and concrete observer objects.
ObserverPatternDemo.java

/**
 * 
 */
package com.dineshonjava.observer.pattern;

/**
 * @author Dinesh.Rajput
 *
 */
public class ObserverPatternDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//create a facebook post i.e. a subject
		FacebookPost facebookPost = new FacebookPost();
				
		//create facebook friends i.e. observers
		Observer dinesh = new FacebookFriend("Dinesh");
		Observer arnav  = new FacebookFriend("Arnav");
		Observer anamika = new FacebookFriend("Anamika");
				
		//register facebook friends i.e. observers to the facebook post or friend list i.e. subject
		facebookPost.registerAsAFriend(dinesh);
		facebookPost.registerAsAFriend(arnav);
		facebookPost.registerAsAFriend(anamika);
				
		//tag your friends to the facebook post i.e. observer to subject
		dinesh.setSubject(facebookPost);
		arnav.setSubject(facebookPost);
		anamika.setSubject(facebookPost);
				
		//check if any update is available
		arnav.update();
				
		//new comment added to the facebook post i.e. to subject
		facebookPost.postComment("Hello Observers!!! How are you!!!");
	}

}

Step 5: Let’s run the demo class and verify the output.

Arnav:: No new comment
Comment Posted to Post: Hello Observers!!! How are you!!!
Dinesh:: New comment::Hello Observers!!! How are you!!!
Arnav:: New comment::Hello Observers!!! How are you!!!
Anamika:: New comment::Hello Observers!!! How are you!!!

Previous
Next