in Design Patterns

Observer pattern in Java

 

OBSERVER PATTERN

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.

Observer pattern example

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.

Observer pattern - Observable and Observer objects

 

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:

 

stockPricesChanged(){

mobileDisplay.update(stockUpdates);

stockBoardDisplay.update(stockUpdates);

webdisplay.update(stockUpdates);

}

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 

  1. Observable
  2. Observer

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

 


1 public interface Observable {
2   public void registerObserver(Observer observer);
3   public void removeObserver(Observer observer);
4   public void notifyObservers();
5 }
Observable.java

 

01 import java.util.HashMap;
02 import java.util.ArrayList;
03 import java.util.HashSet;
04 import java.util.Iterator;
05 import java.util.Map;
06 import java.util.Set;
07 public class StockUpdate implements Observable{
08   private Set<Observer> observers;
09   private boolean stockIndexChanged;
10   
11   private float ibm;
12   private float microsoft;
13   
14   public StockUpdate(){
15     observers = new HashSet<Observer>();
16     
17   }
18   
19   
20 
21   public void notifyObservers() {
22   Iterator<Observer> observerIterator = this.observers.iterator();
23   while(observerIterator.hasNext()){
24     Observer observer = observerIterator.next();
25     observer.update(this, null);
26   }
27     
28   }
29 
30   
31   public void registerObserver(Observer observer) {
32     if(observer != null && observer instanceof Observer){
33       this.observers.add(observer);
34     }
35     
36   }
37 
38   
39   public void removeObserver(Observer observer) {
40     if(observer != null && observer instanceof Observer){
41       this.observers.remove(observer);
42     }
43     
44   }
45 
46 
47   public float getIbm() {
48     return ibm;
49   }
50 
51 
52   public void setIbm(float ibm) {
53     if(this.ibm != ibm){
54       this.stockIndexChanged = true;
55       this.ibm = ibm;
56     }
57     this.setStockChanged();
58   }
59 
60 
61   public float getMicrosoft() {
62     return microsoft;
63   }
64
65 
66   public void setMicrosoft(float microsoft) {
67     if(this.microsoft != microsoft){
68       this.stockIndexChanged = true;
69       this.microsoft = microsoft;
70     }
71     this.setStockChanged();
72   }
73 
74     public void setStockChanged(){
75       this.notifyObservers();
76     }
77   
78 }
StockUpdate.java

 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. 

 
As there are many observers, we have introduced a collection- Set which holds the Observer references.
Whenever the notfiyObservers() method is invoked, the collection is iterated and the update method of the Observers is invoked. 
The update method declared in observer interface accepts arguments through which the state can be sent to the Observers.
 
The MobileDisplay.java has implemented the Observer and Display interfaces. The moment when the update method is invoked the message is constructed and the display method is invoked. The MobileDisplay.java and other interfaces are given below.
 



1 
2 public interface Observer {
3   public void update(Observable observable, Object arg);
4 }
Observer.java


1 
2 public interface Display {
3   public void display(String msg);
4 }
Display.java


01 import java.util.Calendar;
02 
03 import com.sun.jmx.snmp.Timestamp;
04 
05 
06 public class MobileDisplay implements Observer,Display{
07 
08   
09   public void update(Observable observable, Object arg) {
10      StockUpdate su = (StockUpdate)observable;
11      String message = "The stock details of ibm :"+su.getIbm()+" and microsoft :"

                          +su.getMicrosoft()+" at "+Calendar.getInstance().getTime();
12      this.display(message);
13   }
14 
15 
16   public void display(String msg) {
17   System.out.println(msg);
18     
19   }
20   
21 }

MobileDisplay.java


01 
02 public class ObserverDemo {
03   public static void main(String[] args) {
04     StockUpdate su = new StockUpdate();
05     MobileDisplay md = new MobileDisplay();
06     
07     su.registerObserver(md);
08     
09     su.setIbm(25);
10     su.setMicrosoft(30);
11     
12     
13     
14   }
15 }
ObservableDemo.java

 

Observer pattern example output:

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.

The java.util.Observable is a concrete class and java.util.Observer is an interface.

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.

Conclusion:

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.

Observer Pattern PPT Download

Observer pattern example download

 

Srinivas Reddy

Srinivas Reddy

An IT - Specialist with loads of experience in Java, J2ee platforms and loves to share his experience on technology with You...

More Posts - Website

Follow Me:
TwitterFacebook

Srinivas Reddy
Written By:

An IT - Specialist with loads of experience in Java, J2ee platforms and loves to share his experience on technology with You...