Code Pumpkin

Observer Design Pattern

June 7, 2017
Posted by Abhi Andhariya

Observer Design Pattern is one of the Behavioral Design Pattern. Observer design pattern is useful when you are interested in the state of an object and want to get notified whenever there is any change. 

Definition

GoF Definition : The Observer Design Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.

The object which is being watched is called the subject. The objects which are watching the state changes are called observers or listeners.


Concept

In this pattern, there are many observers (objects) which are observing a particular subject (object). Observers are basically interested and want to be notified when there is a change made inside that subject. So, they register themselves to that subject. When they lose interest in the subject they simply unregister from the subject. Sometimes this model is also referred to as the Publisher-Subscriber model.


Real-Life Example

Twitter Follow button:  We can think about a celebrity who has many followers on twitter. Each of these followers wants to get all the latest updates of his/her favorite celebrity. So, he/she can follow the celebrity as long as his/her interest persists. When he loses interest, he simply stops following that celebrity. Here we can think of the follower as an observer and the celebrity as a subject.

Observer Design Pattern


Java Implementation

Let's Implement above Twitter Follow Button example using Java.

Java provides in-built platform for implementing Observer pattern through java.util.Observable class and java.util.Observer interface.

However it’s not widely used because the implementation is really simple and most of the times we don’t want to end up extending a class just for implementing Observer pattern as java doesn't provide multiple inheritance in classes.

I prefer having my own Subject and Observer interface and here is my java code implementation of Observer Design Pattern.


import java.util.ArrayList;

/**
 * This interface handles adding, deleting and updating all observers
 */
interface Subject{
	public void register(Observer o);
	public void unregister(Observer o);
	public void notifyAllObservers(String s);
}


/**
 * The Observers update method is called when the Subject changes
 */
interface Observer{
	public void update(String name, String s);
}

/**
 * This class extends Subject interface.
 */
class Celebrity implements Subject{

	private String celebrityName;  //name of the celebrity
	private ArrayList<Observer> followers;  //list of followers
	
	
	public Celebrity(String celebrityName) {
		this.celebrityName = celebrityName;
		followers = new ArrayList<Observer>();
	}

	/**
	 * add follower to the celebrity's registered follower list
	 */
	@Override
	public void register(Observer o) {
		followers.add(o);
		System.out.println(o + " has started following " + celebrityName);
	}

	/**
	 * remove follower from celebrity's registered follower list
	 */
	@Override
	public void unregister(Observer o) {
		followers.remove(o);
		System.out.println(o + " has stopped following " + celebrityName);
	}
	
	
	/**
	 * Notify all the registered followers
	 */
	@Override
	public void notifyAllObservers(String tweet) {
		for(Observer follower : followers)
		{
			follower.update(celebrityName, tweet);
		}
		System.out.println();
	}
	
	/**
	 * This method updates the tweet. 
	 * It will internally call notifyAllObservers(tweet) method 
	 * after updating the tweet. 
	 * 
	 */
	public void tweet(String tweet)
	{
		
		System.out.println("\n" + celebrityName + " has tweeted :: " + tweet + "\n");
		
		notifyAllObservers(tweet);
	}
	
}

/**
 * This class extends Observer interface.
 */
class Follower implements Observer{

	private String followerName;
	
	public Follower(String followerName) {
		this.followerName = followerName;
	}

	/**
	 * This method will be called to update all followers regarding the 
	 * new tweet posted by celebrity.
	 */
	@Override
	public void update(String celebrityName , String tweet) {
		System.out.println(followerName + " has received "+ celebrityName + "'s tweet :: "+  tweet);
		
	}

	@Override
	public String toString() {
		return followerName;
	}
	
	
}

public class ObserverDesignPattern {

	public static void main(String[] args) {
		Celebrity amirkhan = new Celebrity("Amirkhan");
		Celebrity selenaGomez = new Celebrity("Selena Gomez");
		
		Follower amar = new Follower("Amar");
		Follower juhi = new Follower("Juhi");
		Follower urja = new Follower("Urja");
		Follower malay =  new Follower("Malay");
		Follower ankit = new Follower("Ankit");
		Follower harsh =  new Follower("Harsh");
		
		amirkhan.register(amar);
		amirkhan.register(juhi);
		amirkhan.register(urja);
		
		selenaGomez.register(malay);
		selenaGomez.register(ankit);
		selenaGomez.register(harsh);
		
		amirkhan.tweet("Hey guys, came across this interesting trailer, check it out.");
		selenaGomez.tweet("Good Morning..!!");
		
		amirkhan.unregister(juhi);
		
		amirkhan.tweet("Teaser of Secret Superstar has been released..!!");
		
	}

}

Download Complete Java Program »

output:


Amar has started following Amirkhan
Juhi has started following Amirkhan
Urja has started following Amirkhan
Malay has started following Selena Gomez
Ankit has started following Selena Gomez
Harsh has started following Selena Gomez

Amirkhan has tweeted :: Hey guys, came across this interesting trailer, check it out.

Amar has received Amirkhan's tweet :: Hey guys, came across this interesting trailer, check it out.
Juhi has received Amirkhan's tweet :: Hey guys, came across this interesting trailer, check it out.
Urja has received Amirkhan's tweet :: Hey guys, came across this interesting trailer, check it out.


Selena Gomez has tweeted :: Good Morning..!!

Malay has received Selena Gomez's tweet :: Good Morning..!!
Ankit has received Selena Gomez's tweet :: Good Morning..!!
Harsh has received Selena Gomez's tweet :: Good Morning..!!

Juhi has stopped following Amirkhan

Amirkhan has tweeted :: Teaser of Secret Superstar has been released..!!

Amar has received Amirkhan's tweet :: Teaser of Secret Superstar has been released..!!
Urja has received Amirkhan's tweet :: Teaser of Secret Superstar has been released..!!


The most popular use of Observer pattern is in Model View Controller (MVC) architectural pattern.

Memory leaks

Main issue with Observer pattern is that it can cause memory leaks. The subject holds a strong reference to observers. If observers are not de-registered in time, it can lead to memory leak.

Existing Implementation in JDK and J2EE

  1. java.util.Observer/java.util.Observable (rarely used in real world though)
  2. All implementations of java.util.EventListener (practically all over Swing) . In Swing, the whole concept of listeners is based on this pattern. For example, you can define a listener for a button in a UI and if the button is selected, the listener is notified and performs a certain action. In this case, the ActionListener is the Observer and the button is your Subject. 
  3. All Servlet Event and Listeners e.g. ServletContextEvent and ServletContextListener. The  ServletContextEvent is fired when web application is deployed on the server. If you want to perform some action at the time of deploying the web application such as creating database connection, creating all the tables of the project etc, you need to implement ServletContextListenerinterface and provide the implementation of its methods.
  4. javax.servlet.http.HttpSessionBindingListener
  5. javax.servlet.http.HttpSessionAttributeListener
  6. javax.faces.event.PhaseListener
  7. Java Message Service (JMS) uses Observer Design Pattern along with Mediator Design Pattern to allow applications to subscribe and publish data to other applications.

That's all for this topic. If you guys have any suggestions or queries, feel free to drop a comment. We would be happy to add that in our post. You can also contribute your articles by creating contributor account here.

Happy Learning 🙂

If you like the content on CodePumpkin and if you wish to do something for the community and the planet Earth, you can donate to our campaign for planting more trees at CodePumpkin Cauvery Calling Campaign.

We may not get time to plant a tree, but we can definitely donate ₹42 per Tree.



About the Author


Surviving Java Developer, Passionate Blogger, Table Tennis Lover, Bookworm, Occasional illustrator and a big fan of Joey Tribbiani, The Walking Dead and Game of Thrones...!!



Tags: , ,


Comments and Queries

If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code class="java"> 
String foo = "bar";
</code></pre>
For more information on supported HTML tags in disqus comment, click here.
Total Posts : 124
follow us in feedly

Like Us On Facebook