I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 639 posts at DZone. You can read more from them at their website. View Full User Profile

Design Patterns Uncovered: The Observer Pattern

02.03.2010
| 72897 views |
  • submit to reddit

Design patterns are one of the most valuable tools for developers. They illustrate the best design solutions that others have encountered, and allow you to apply the same principle to your own designs. More importantly, knowing design patterns gives a common vocabulary for software developers to use when talking about their designs.

In this article series, I'll be going through each pattern and describing how it's used and where it's applied in the real world.  To start off, I'll be describing one of the most used design patterns, the Observer pattern. 

Design Patterns Refcard
For a great overview of the most popular design patterns, DZone's Design Patterns Refcard is the best place to start.

The Observer In The  Real World

Before we get into the theory and code behind the Observer, let's take a look at a real world example, such as RSS feeds.  When I want to get updates from a particular feed, I add it to my feed reader. Any time that the RSS feed has an update, it will appear in my reader automatically.  This is the Observer pattern in action, a publisher/subscriber relationship with one source having many subscribers. 

The Observer Pattern

Of all of the design patterns that are out there, the Observer is one that you've probably used already, even if you weren't aware of it. The Observer pattern is the gold standard in decoupling - the seperation of objects that depend on each other.

The Observer is known as a behavioural pattern, as it's used to form relationships between objects at runtime.  The definition provided in the original Gang of Four book on Design Patterns states: 

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

Let's take a look at the classic diagram definition of  the observer:

The idea behind the pattern is simple - one of more Observers are interested in the state of a Subject and register their interest with the Subject by attaching themselves. When something changes in our Subject that the Observer may be interested in, a notify message is sent, which calls the update method in each Observer.
When the Observer is no longer interested in the Subject's state, they can simply detatch themselves. The following sequence diagram illustrates the registration and notification flow in action.

The benefits here are quite clear. To pass data onto the observers, our subject doesn't need to know who needs to know. Instead, everything is done through a common interface, and the notify method just calls all the objects out there that have registered their interest. This is a very powerful decoupling - meaning that any object can simply implement the Observer interface and get updates from the Subject. 

Where Would I Use This Pattern?

In general, you want to use this pattern to reduce coupling. If you have an object that needs to share it's state with others, without knowing who those objects are, the Observer is exactly what you need.

You'll have seen, and probably used, the Observer many times if you've done any UI programming, especially in Swing. The whole concept of listeners is based on this pattern. The event listener is the most popular, where you register an ActionListener to a UI control, such a button, and react to action events using the actionPerformed method. In this case, the ActionListener is the Observer and the button is your Subject. As the button changes state, you can react, if you choose to, in your actionPerformed method. 

The typical real world uses of the pattern all revolve around this type of event handling system. 

So How Does It Work In Java?

While some patterns require you to define the interfaces that make the pattern work, the Observer is a case where Java has the work done for you already in the java.util package.

 

The slight difference from the classic definition is that Observable is used in place of the Subject and is implemented as a class, while the Observer interface remains the same. Let's take a look at an implementation of the pattern with a real example. In our example, the subject will be a DataStore, with a Screen class as the observer.

First, let's make our DataStore class observable by extending the java.util.Observable class. This means that our DataStore has all the methods and functionality available to make it a Subject, according to our pattern. 

import java.util.Observable;

public class DataStore extends Observable
{

private String data;

public String getData()
{
return data;
}

public void setData(String data)
{
this.data =data;
//mark the observable as changed
setChanged();
}
}

You'll notice that we have called the setChanged() method of the Observable. This is necessary in order for the call to notify observers to send out the update. Without this set, the Observable will see no reason to send out the update. 

Next, let's create our Observer. To do this, all we need to do is implement the Observer interface which forces us to write an update method, to deal with changes in the Observable's state. 

public class Screen implements Observer {

@Override
public void update(Observable o, Object arg) {

//act on the update
}

}

Adding our Screen as an observer to the DataStore is simple: 

Screen screen = new Screen();

DataStore dataStore = new DataStore();
//register observer
dataStore.addObserver(screen);

When the data changes, we want to notify all observers of this object. To do this, we just need to call the notifyObservers method when we want an update sent out 

//send a notification
dataStore.notifyObservers();

As you can see it's a really simple pattern to understand, and even easier to use thanks to the Java implementation of the pattern. 

Watch Out for the Downsides

As with any piece of code, you need to be careful how you use the Observer pattern. Martin Fowler has a good list of gotchas for the observer.  In his article he mentions that it can be difficult to see the path through the code, unless you are debugging. As such, you should be careful not to have chains of observers (observers acting as subjects). Also, watch out for memory leaks as the subject will hold a reference to the observer unless it has deregistered. 

Other Articles in This Series
The Observer Pattern
The Adapter Pattern
The Facade Pattern
The Factory Method Pattern
The Abstract Factory Pattern
The Singleton Pattern
The Strategy Pattern
The Visitor Pattern

 

 

Tags:

Comments

Marcin Świerczyński replied on Wed, 2010/02/03 - 5:28pm

Great idea, thanks! However, IMO it would be better to describe our own implementation of this pattern. First of all, it can be a good showcase of what's going on under the hood. Secondly, using a standard implementation enforce us to use inheritance so "subject" class won't be able to extends anything else.

Gervais Blaise replied on Thu, 2010/02/04 - 3:22am

Ok, I know the observer pattern but actually I write many Swing apps where we use "Listeners". So it seems that they do the same work.

So, what are the difference between "Observer" and "Listener". Where and why to use one of them ?

Daniel Tuchtenhagen replied on Thu, 2010/02/04 - 4:05am

When talking about Observers, one may mention M.Fowlers Observer Gotchas:

 http://martinfowler.com/eaaDev/OrganizingPresentations.html#observer-gotchas

 Always good to know downsides.

Slava Lo replied on Thu, 2010/02/04 - 4:26am

With the RSS example, is it really going to be optimal solution to use Observer pattern, considering the amount of possible subscribers?

 

Mladen Girazovski replied on Thu, 2010/02/04 - 6:38am in response to: Gervais Blaise

So, what are the difference between "Observer" and "Listener". Where and why to use one of them ? 

"Observer"  is the official name of thepattern (or at least the name used by the GoF),"Listener" is "colloquial" for the same thing.

 

James Sugrue replied on Thu, 2010/02/04 - 10:22am in response to: Slava Lo

True, RSS may not be the best example, but I just mention it here to illustrate the publisher/subscriber concept.

James Sugrue replied on Thu, 2010/02/04 - 10:24am in response to: Daniel Tuchtenhagen

Thanks for the link - that is a really good list of downsides to the pattern. I've added these on to the end of the article, and will keep the downsides in mind for future articles in the series.

 

John Turner replied on Wed, 2010/03/31 - 7:37am

I think with design patterns, it is always very useful to discuss some of the implementation decisions that need to be made when using a particular pattern.  For example:

* When is most appropriate for the Observable to perform notifications and what are the trade off's being made.

* What is the appropriate level of detail to pass to the Observer and what are the trade off's being made.

By definition, a design pattern allows for variation in its implementation and it is the variation that I personally find most interesting.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.