Need for Observer pattern:
Any critical application will have a need to monitor the changes in Data and keep notifying the instances that are interested in changes. Let us consider a simple example to understand the need and applicability of the Observer Design pattern with a stock market example.
The stock prices change very frequently and these are the critical data which needs to be updated to different systems when changed.
When a stock price changes, the data will be changed on the stock market display boards, updates will be sent to the mobile apps and websites that display the stock prices.
In the above requirement, we have three observers(Stock market board, mobile apps, websites) which are interested to get notifications when the data of stock prices changes.
Observer pattern helps to design your application to implement this kind of notification requirements and helps to easily add more observers with less or no changes to the application.
The Observer design pattern gives better flexibility and maintainability to applications as the design is prepared based on the Object oriented design principles.
Observers and Observable – Terminology
Let us look into the terminology of Observer pattern. I have a class StockUpdate.java which keeps monitoring the stock prices and has a state which holds the stock prices.
The StockBoardDisplay.java, MobileDisplay.java and Webdisplay.java are waiting for the notifications about the changed stock prices.
Here, the StockUpdate instance which has the state about the changed stock prices is an Observable object and instances which are interested to get notifications are observers.
Without Observer pattern
If we do not have an idea about the observer pattern design, a novice programmer would go ahead to write the stockPricesChanged() method as given below:
we may directly call all the Observers update methods. But, what if there are more observers to be added?
The stockPricesChanged() method should be updated and also a new instance variable of Observer will be added to the StockUpdate class which creates more dependency between the Observable and Observers. This leads to violation of Object Oriented design principle to maintain less dependency.
Observer pattern – Design
Program with Interfaces – A design principle of Object oriented programming. So the first step in creating a design for observer pattern is to create to Interfaces.
Interfaces are good and using them will reduce the dependency between the instances. So, let us create two interfaces
The responsibility of observable is to help register, remove and notify observers. So we will define three methods in Observable interface – registerObserver(), removeObserver() and notifyObservers()
As we are using the Interfaces to refer the instances, the dependency between the Observer instance and Observable implementations can be avoided directly as they refer each other with the help of interfaces.
The Observable instance should update one or more observers. So, the relation between the Observable and Observers is one to many relationship. Due to this, the Observable implementation should maintain a collection to hold the references of Observers.
Continued in Page 2
The StockUpdate.java has implemented all the methods mandated by the Observable interface and it has two stock prices, one is ibm and the other is Microsoft. Whenever the setter methods of these variables are invoked, we are changing the stockChanged variable to true and call thesetStockChanged() method from which the notifyObservers() method will be called.
Observer pattern example output:
Inbuilt Observer pattern in Java
There is a support for Observer pattern in the JDK itself. The java.util package has Observer and Observable declared for the sake of Observer pattern.
A small negative side effect in using the java.util.Observable is that our Observable implementation will not have a chance to inherit any other class.
It is always better to declare our own Observable interface and go ahead with the implementation.
Observer pattern is used in lot areas and a well know example is event and listeners for the JButton clicks. The next example is Java RMI.
This pattern is simple and more flexible and makes the code more maintainable.