In this blog post, I will explain the observer design pattern, a type of behavioural design pattern.
This post is part of the Design Patterns in Java Series. Check out the full list of covered patterns there.
Why Should You Use the Observer Design Pattern?
The high-level problem behind the observer pattern is the need for an object to inform another object that a change has occurred.
It’s easier to think about it in terms of subscribing to a newsletter (such as the one for this blog :)). Every time there’s a new email being sent, it gets delivered to your email account. As long as you remain a subscriber, you get new emails and if you unsubscribe, you stop receiving them. Also, a newsletter can have multiple subscribers, so we have a one-to-many relationship at play.
When people talk about the observer pattern, they might also refer to it as the Hollywood principle: “Don’t call us, we’ll call you.”. The idea here is that Hollywood agents prefer to call clients when a new role pops up, instead of being constantly called by clients. This allows for a more efficient use of the agent’s time, as they can look to fill in a role as soon as the role becomes available.
In software, a use case for the observer pattern might be in a chat application. Let’s say you have a chat server and multiple chat clients connected to this server. It would be inefficient for clients to constantly check if new messages have been posted to the server. A better approach is for a newly sent message to be “pushed” to all subscribed clients.
Another example would be in programming graphical user interfaces. We often want to “listen” for different events that happen on the interface such as button clicks or mouse movements. Using such “listeners”, we can subscribe to UI changes.
What is the Observer Pattern?
Here’s the definition from the Head First Design Patterns book:
The Observer 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.
In software, we call the publisher the subject and the subscribers the observers.
Essentially, when the subject changes its state, it notifies the observers about the change.
As always, let’s take a look at the observer pattern’s class diagram.
Observer Pattern Class Diagram
As can be seen in the figure, all concrete observers must implement the Observer
interface. The interface has one method that is called by the subject to notify the observers about a state change.
Each subject maintains a list of registered observers and calls the notifyObservers
method to inform these observers about any updates or state changes. The subject also has methods for registering and unregistering observers.
Pros
- loose coupling – subject only knows that an observer implements the
Observer
interface, without concerns for concrete implementations.
- flexibility – can dynamically register and unregister observers.
Cons
- observers are notified in random order.
How Can You Implement the Observer Pattern?
Let’s take a look at a simple Java program that uses this pattern. To make things easier, Java provides an out-the-box implementation of the observer pattern.
Observer Pattern Java Code Example
In our program, a blog informs its subscribers when a new blog post is published.
Firstly, we need to create a class that extends the Observable
class.
Secondly, we need to create a class that observes the Blog
for changes. The class must implement the Observer
interface.
Lastly, we register the Subscriber
observer with the Blog
observable and create some blog posts.
The output should be as follows:
Observable
Interface Deprecated in Java 9
The Observable
interface has been deprecated since Java 9. As pointed out in this StackOverflow answer, a few reasons for why it’s been deprecated are as follows:
- not thread-safe – the methods can be overridden by its subclasses, which disrupts thread safety.
- not serializable – the
Observable
class couldn’t be serialized as it didn’t implement the Serializable
interface and all of its members were private.
- poor event model – we don’t know what has changed, just that something has changed (more info).
So what’s the alternative to Observable
? We can use the PropertyChangeListener
interface from the java.beans package instead.
Example Implementation with PropertyChangeListener
With this approach, an observable must keep a reference to an instance of PropertyChangeSupport
. That documentation page gives an example of how the class should be used. For the code sample below, I’ve also adapted code from a blog post on baeldung.com.
The new observable would look like so:
With this support
object, one can add or remove observers, and notify them about state changes:
Here, the first argument is the name of the observed property, the second is the old value of the property, and the third is the new value respectively.
Observers would then need to implement the PropertyChangeListener
interface:
As we’re employing the PropertyChangeSupport
class, the new property value can be fetched from the event. Let’s test the things together:
Summary
-
In the observer pattern, a subject notifies its observers about state changes.
-
As the Observer
interface is deprecated, the PropertyChangeListener
approach is preferred.