The three main components of the Observer design pattern are: Subject, Observer and ConcreteObserver.
The observer pattern is one of the commonly used patterns. You’ll find it not only used in your own code, but you’ll find it used in various libraries and code bases. And unlike the strategy pattern which can be bit abstract to get your head around, the observer pattern is easily explained in the form of a real-world strategy.
Think about your standard newspaper magazine subscription. A publisher creates a newspaper and starts publishing it, you subscribe to the newspaper and as long you stay subscribed you’ll get issues. You can unsubscribe at any time and you’ll stop getting issues. Other people can subscribe too and they’ll all receive issues if they are published and if they stay subscribers. And if publisher ever goes out of business, obviously, you’ll stop receiving issues.
To make this example a little more formal, let’s think about a publisher and subscribers as sets of objects. We’ll start with the publisher object which any other object can send a request to subscribe, when their request is received by the publisher, the requesting object immediately becomes a subscriber. It is important that any object can be a subscriber, which means we don’t care what kind of object makes the request. Not to mention there will be objects that are not subscribers as well. We should also take note that the subscriber typically holds data of interest. That could be a stock quote, a weather temperature or any kind of data that could be interesting. And when the data changes, the subscribers are notified.
Here’s the definition of the Observer pattern:
The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updates automatically.
Let’s begin with the subject defining an interface. This interface includes two methods that allow dependents to register or remove themselves from observing the subject, and includes a notify observers method that we’ll talk about in a moment.
The Observer interface just has one method called update, that’s what subjects call to let the dependents know data in the subject has changed. Now depending on your design when update is called, the dependents maybe sent a new value as part of the update call or the dependents might have to ask the subject explicitly for the new value.
The concrete subject implements notify Observers method which is called anytime data changes and this method calls the update method on each observer. It is also common to implement getters and setters in the subject to get and set the change.
The concrete observer can be any class that wants to implements the observer interface. All the concrete observer needs to do is implement the observer interface which contains the update method and that must call the subject as necessary.
Implementing the Observer Pattern
To illustrate the Observer pattern, we’ll implement a simple weather station. The weather station consists of a weather data class that can read weather information like humidity, the temperature and pressure. And the display classes that display this weather data in various configurations, like the current conditions, forecast, and statistics of the temperature like max and min temperature of the day. Each time the weather data gets new weather data it needs to update each of the displays. So, the weather data class is the subject, and the displays are the observers. They are dependent on the weather data object to let them know when there’s new data to display.
Here’s the class diagram for the weather station. We’ve got the subject interface the register observer, remove observer, and notify observer methods. And the weather data class will implement the interface, implementing each of those methods along with other concrete methods to get the weather data. We’ve also got an observer interface with one method update. Each of the displays implement this interface. And we’ve added another interface display element, which all the display classes implement as well. Each of the display class has a reference to the weather data subject, so they can register themselves as observes. And the subject weather data keeps a list of all the observers it has, so it can notify the observers when it gets new weather information.
Now, let’s look at the code for each.
Let’s begin by look at the three interfaces. We have the subject interface which has three methods. Register observer, which observers will call to register themselves with the subject. Remove observers, which observers will call to remove themselves as observers. And notify observers, which the subject will call to notify observers when there’s a change.
The observer has just only one method, update. This is the method that the subject will call when it needs to notify an observer of a change.
And the display element interface just for our convenience. This is the interface that all the display classes will implement, and they all need to implement the display method. So we can call this to get the weather information from the main class.
Now let’s check out the weather data class.
Weather data is our subject, so it implements the subject interface. The subject must keep track of all its observers. So, the weather data class has an array list observers that holds all the observers. We create this array list in the constructor of the weather data class. The register observer method simply adds an observer to this array list. And the remove observer method removes the observer from the list. Notice that both these methods take observer as an argument. And you’ll see shortly when we look at the observer code that when an observer calls these methods it passes itself in as the argument.
Now let’s look a the notify observers method.
This is how the weather data subject notifies all its observers when the change occurs. The method iterates through all the observers in the observer’s array lists and calls the observers update method, passing in the current values for its state, temperature, humidity, and pressure. If we look back at the top of the class, you’ll see those fields defined. How does this variable get set? We can set these measurements using the set measurements method.
Notice that the sets measurements method calls measurements changed, which then simply calls notify observers. Finally, we have getter methods for three properties, just in case the properties are needed for any other classes.
Now let’s look at the observers.
The current conditions display class implements the observer and display element interface. So, it needs to implement the update and display methods. First, let’s look at the constructor. When we create a display object and pass in the subject weather data, that’s so an observer can call the subjects methods like register observer to be added to the list of observers. In the constructor, we save the reference to the weather data object and then use it to register this object as an observer. The current conditions display is notified the change from the weather data object when its update method is called. The update method receives the new weather data information and saves the data that’s needed by the display. The current condition saves the temperature and the humidity, but doesn’t bother saving the pressure because it is not needed for this display. And whenever the display element gets new data form the subject, it needs to update its display showing the new data so we call display which simply prints the new current conditions to the console.
So, we have our subject and we have our observers, so let’s look at the main class.
Here we can see how we put everything together. The first thing we do in the weather station is to create our subject, a weather data object. Then we crate three observers for our weather station, a current condition display, a statistic display, and a forecast display. And we pass the weather data object to each observer. Remember that each observer saves the weather data object and then immediately calls the register object method to register itself as an observer. Then we change the data in the weather data subject simulating the weather station reporting new data from sensors. When we do this the weather data object notifies each of the observers of the change which causes each observer to update its display. We should see each observer create an updated display each time we change the data by calling set measurements.
Because we used the observer pattern, we can easily add new displays at any time without changing the weather data class at all. The weather data class doesn’t know any specifics of the observers; it just knows how to keep track of them and update them when weather changes.
Burris, Eddie. “Chapter 8 Factory Method.” Programming in the Large with Design Patterns. Leawood, Kan: Pretty Print, 2012. 110-122. Print.
Freeman, Eric, and Elisabeth Freeman. “Chapter 4. The Factory Method Pattern: Baking with OO Goodness.” Head First Design Patterns. Sebastopol, CA: O’Reilly Media, 2005. N. pag. Print.
Foundations of Programming: Design Patterns. Lynda.com.