Observer pattern is a classic design pattern with an intent to define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. In the previous post I implemented the pattern the classical way, where the observer is responsible of getting the state from the subject. In this post I’ll show a specialization of this pattern. This is a continuation of the previous post. So if you have not already had a look at it, I humbly advise you to do so. Otherwise some concepts might not be clear to you.
Providing the state as a parameter
In the typical case, the observer is responsible of getting the updated state from the subject. This means that the observer has to hold a reference to the subject (also the subject holds a reference to the observer, meaning we have created a circular reference). All the observer cares about is the updated state, not the subject itself. A specialization of this pattern dictates that the updated state should be passed as a parameter to the update()
method on the observer.
Code examples
I’m going to use the same example domain as in the previous post. In short, we have a subject which publishes to its subscribers how many people are in space right now. Most of the code will remain the same but let’s look at the differences. First of all, the interfaces have changed slightly.
The update()
method takes the state as a parameter. Additionally getState()
method is removed from the Subject interface.
The only noticeable difference (other than the removal of getState()
) in the concrete implementation of the Subject interface is notifyObservers()
. The updated state is passed as an argument to the update()
method.
As you might imagine, the only change in the concrete implementation of the Observer interface is the update()
method.
Creating observers with lambda expressions
The fact that the updated state is passed as a parameter and the observer does not have to hold a reference to the subject, it is easy to create new observers with lambda expressions.
Keep in mind that this will only work if your Observer interface defines one and only one method. If you wish, you can also use anonymous inner classes to create new observers.
Conclusion
The observer pattern is used a in a lot of frameworks and libraries. Many GUI toolkits use it under the hood. The JDK includes Observer and Observable interfaces so you don’t have to implement everything by yourself. Keep your eyes open and you might see this pattern implemented in some shape or form.