Design Patterns: A quick guide to Observer pattern in Java
Design Patterns: A quick guide to Observer pattern in Java
Take for an example, web sockets, they help in creating full duplex communication between the client and servers. If you are trying to create a chat application , it is obvious that there will be user created events, http requests and responses. The observer design pattern is best suited to implement such systems. In such systems , the observer object that is waiting to get notified via a stream of events has no control over the emitted stream of events by the subject. The observer (user1 object) subscribes to a subject (‘that emits messages’) from another observer (user2 object). In this case user1 object has no control over what is emitted to it, only that it is notified of some state change. The design pattern of classes while using the observer design pattern is such that the subject does not know anything about them , it only is aware that it the observers implement the observer interface and how it can notify them about changes. We will see a simple example of observer design pattern in java, in a bit.
What is observer design pattern?
It is easier to understand concepts by using some analogy. So, here is one for you. Think of an email blog subscription.
You visit this really cool site that writes articles on interstellar stuffs.
You then subscribe to a particular topic , say space aliens. As long as you subscribe to that email list, you will get the articles.
If you unsubscribe from that email list, you will not get emails from them.
There will definitely be other subscribers and un-subscribers as well.
Read: "What does DevOps actually do?"
This is what the observer design pattern is all about. The publisher (email blog company) and the subscriber (you) together form the observer pattern. And in the lingo of software engineers, the publisher is the subject and the subscriber is the observer. So, basically the subject broadcasts any state change that happens and the observers listen to the updates and displays those changes. Okay, but why use observer design pattern? What is the point of using it?
Why use observer design pattern?
Lets get back to the chat application example we used in the introductory paragraph. You will want to use web sockets to create a full duplex communication between the client and server, otherwise no one would want to use a chat application that needs a page refresh to fetch new messages. Since, web sockets solve that problem and there are libraries that implement it , your problem has already been solved. However, it is necessary to know that the pattern most libraries follow is based on the observer design pattern. This awareness will help a lot when designing a system that requires a common interface to updates its dependencies in one go. What we have achieved with webs sockets is asynchronous behaviour, updating dependencies when state change and that happens automatically. So, why use observer design pattern? What problems can be solved with it?
Read: "Factory Design Patterns in Java"
Lets see the bullet points below for the benefits of observer design pattern and that should clear your doubt on “why use observer design pattern”?
Benefits of Observer design pattern
The observer design pattern provides an object design pattern where subjects and observers are loosely coupled. The subject does not need to know everything about the concrete class that the observer implements, it should just be aware of the implementation.
Since, they are loosely coupled , we can add as many observers we like, and replace as many as we want, without having to modify a lot of things.
The subject does not need to be modified to add other types of observers. Without the concept of observer design pattern or design patterns in general , we would have messed up the subject’s implementation.
The subjects and observers can be reused independently of each other because of loose coupling.
Changes to either the subject or an observer will not affect the other as long as they are not messed up completely. The observer design pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
We can achieve asynchronous behaviour of our code with such pattern, and ultimately the end goal is to create a code base that is extensible, maintainable and reusable.
Why does observer design pattern fall in the category of behavioural design pattern?
Behavioural Design Patterns are those design patterns that deal with interaction between objects and how they communicate. As you can guess now that observer design pattern follows the same approach, the subject holds the state and communicates it to the observers whenever there is a change in state.
Example of observer design pattern in java
The common approach to this design pattern is to have the following things kept in mind:
Subject – that keeps track of all observers and broadcasts any changes in the state.
Observers- these implement a common interface that subscribe to the subject for getting updates.
This way we can decouple the behaviour of objects from each other as well as the core class. So, how can you implement the observer design pattern in java?
1. Start by declaring a subject interface.
Fig- Observer Design Pattern in Java – Subject Interface
This interface has 3 methods –
registerObserver – As the name suggests, it registers the observers with the subject.
removeObserver- It is used to unsubscribe from the subject.
notifyObservers- It is used to update the observers for any state change.
2. Declare an Observer
Fig- Observer Design Pattern in Java – Observer Interface
The update method is self explanatory, it updates the state of the observers.
3. Implement the subject interface
Fig- Observer Design Pattern in Java – Subject Interface Implementation
The subject class has additional stuffs, beyond what the interface provides.
Class properties - List is used to store the observers and value is a simple integer that can be considered a state value.
Methods- setValue method simply sets the value and notifies the observes for change.
Constructor- The constructor simply initialises the array list object to keep track of different observers.
Others are basically the implementation of the interface methods as already described.
4. Implement the observer interface
Fig- Observer Design Pattern in Java – Observer Interface Implementation
This is just on instance of implementing the simple observer class. We can implement as many as we need. Apart from implementing the update method there are several additional stuffs, lets check them one by one.
Class Properties- There are two variables declarations value and simpleSubject.
Constructor – Now this is where the observer design pattern is playing a key role. The Subject class is being passed as a parameter and from within the Observer it is being registered. Notice that observers register themselves when needed, the subject only does that when asked to do it.
There is an additional display method that prints out the value, or changed value.
5. Combining all these together
Fig- Observer Design Pattern in Java – Test Drive
See, how all these make sense now? The Subject class’s instance has everything that allows us to register the observer, update the value and notify the changes. The Observer class has the mechanism to register itself with the Subject and once the value is updated, the observer method is called inside of the Subject to broadcast the state change. The event driven systems may have the same approach to implement their version of “subject” and “observers”. Java’s Swing makes use of the Observer Pattern, as do many GUI frameworks, if you have ever used one, you may realise the pattern now.
Where else can observer design pattern be applied?
One final benefit of observer design pattern we did not mention rigorously is its use in frameworks and also standardising its approach to core programming languages’ standard library. Java has its own observer design pattern library and so does python. State management libraries like Redux have been built upon its principles. Web sockets , blockchains, distributed databases, or situations where data is not available to the CPU at start up.
Common misconception: Design Patterns do not remove dependencies completely, otherwise there will be no point of relating one class to the other. The point is to reduce it.
So, this was observer design pattern in java, you can use it any programming language of your choice. Now you can explain ‘why use observer design pattern?’ to anyone verbosely, because if you grasp the basics, explanation and implementation is easy. To summarise the reason, you can see that the code above is pretty much extensible. We can implement as many Subjects and Observers we like without having to distort the concrete classes and the interfaces. Also, every time some changes happen in the values (state) of the classes, it is taken care of by the subject, and we do not have to write messy code to update it using a bunch of conditions.