Observer Pattern
- 24th May 2018
- 0
- 6254
- how observer design pattern works how observer pattern is implemented how to implement observer design pattern observer design pattern in java observer design pattern in java with example observer pattern implementation Observer Pattern in java Observer Pattern in java with an example
Observer Pattern is one of the behavioural design patterns.
It defines a one-to-many dependency between objects so that when one object changes its state, all of its dependents are notified and updated automatically.
In this pattern, it is very important to understand below terms
Subject : The object which is being watched is called the subject.
Observer (or) Listener : The objects which are watching the state changes are called observers or listeners
Example :
The best example for Observer pattern is the Event listener in Java
Event is the subject and listener is the observer
There can be many listeners for one event.
Subject :
It contains a list of all observers to whom notification has to be made for any change in the state of Subject.
Subject should provide a method using which observers can register/unregister themselves for the notification of subject’s state change.
Subject should also provide a method to notify all the observers if any change in its state.
Observer :
Observer should provide a method to set the object to watch the Subject’s state change
Observer should also provide another method that will be used by Subject to notify Observer for any change in its state.
Java provides inbuilt mechanism for implementing Observer pattern through java.util.Observable class and java.util.Observer interface.
However it’s not best option as most of the times we don’t want to end up extending a class just for implementing Observer pattern as java doesn’t provide multiple inheritance in classes.
Let’s see how to implement Observer pattern
Step 1
Create an interface to represent Subject
- package com.kb.observer;
- public interface Subject {
- public void registerObserver(Observer observer);
- public void removeObserver(Observer observer);
- public void notifyObservers();
- }
package com.kb.observer; public interface Subject { public void registerObserver(Observer observer); public void removeObserver(Observer observer); public void notifyObservers(); }
Step 2
Create an interface to represent Observer
- package com.kb.observer;
- public interface Observer {
- public void update(float temperature,float humudity);
- }
package com.kb.observer; public interface Observer { public void update(float temperature,float humudity); }
Step 3
Create a class implementing the Subject
- package com.kb.observer;
- import java.util.ArrayList;
- import java.util.List;
- public class WeatherData implements Subject{
- private float temperature;
- private float humidity;
- private List<Observer> observers;
- public WeatherData() {
- observers=new ArrayList<>();
- }
- @Override
- public void registerObserver(Observer observer) {
- observers.add(observer);
- }
- @Override
- public void removeObserver(Observer observer) {
- observers.remove(observer);
- }
- @Override
- public void notifyObservers() {
- for (Observer observer : observers) {
- observer.update( temperature, humidity);
- }
- }
- public void weatherChanged(float temperature,float humidity){
- this.temperature=temperature;
- this.humidity=humidity;
- notifyObservers();
- }
- }
package com.kb.observer; import java.util.ArrayList; import java.util.List; public class WeatherData implements Subject{ private float temperature; private float humidity; private List<Observer> observers; public WeatherData() { observers=new ArrayList<>(); } @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update( temperature, humidity); } } public void weatherChanged(float temperature,float humidity){ this.temperature=temperature; this.humidity=humidity; notifyObservers(); } }
Step 4
Create a class implementing Observer
- package com.kb.observer;
- public class WeatherDataConsumer implements Observer{
- @Override
- public void update(float temperature,float humidity) {
- System.out.println("Changed weather data ");
- System.out.println("temperature -> "+temperature);
- System.out.println("humidity -> "+humidity);
- }
- }
package com.kb.observer; public class WeatherDataConsumer implements Observer{ @Override public void update(float temperature,float humidity) { System.out.println("Changed weather data "); System.out.println("temperature -> "+temperature); System.out.println("humidity -> "+humidity); } }
Step 5
Create a client class to test the pattern
- package com.kb.observer;
- public class ObserverPatternClient {
- public static void main(String[] args) {
- WeatherData weatherData = new WeatherData();
- //create observers
- Observer observer1 = new WeatherDataConsumer();
- Observer observer2 = new WeatherDataConsumer();
- Observer observer3 = new WeatherDataConsumer();
- //register observers to the subject
- weatherData.registerObserver(observer1);
- weatherData.registerObserver(observer2);
- weatherData.registerObserver(observer3);
- weatherData.weatherChanged(40, 35);
- weatherData.removeObserver(observer3);
- weatherData.weatherChanged(40, 35);
- }
- }
package com.kb.observer; public class ObserverPatternClient { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); //create observers Observer observer1 = new WeatherDataConsumer(); Observer observer2 = new WeatherDataConsumer(); Observer observer3 = new WeatherDataConsumer(); //register observers to the subject weatherData.registerObserver(observer1); weatherData.registerObserver(observer2); weatherData.registerObserver(observer3); weatherData.weatherChanged(40, 35); weatherData.removeObserver(observer3); weatherData.weatherChanged(40, 35); } }
In the output, we can see that initially there are 3 observers are registered and hence Subject state change is notifying all 3 observers and So it prints weather data 3 times
After that we removed one observer from Notification list and hence next time we can see its notifying 2 observers.
Important points about Observer pattern
Using the observer pattern a subject can register an unlimited number of observers.
If a new listener wants to register with the subject, no code change in the subject is necessary.
Using the listener pattern decouples the subject from its observers. Only the observers have direct knowledge about the subject.
Observer design pattern is also called as “publish-subscribe pattern”.
Some of its implementations are
• java.util.EventListener in Swing
• javax.servlet.http.HttpSessionBindingListener
• javax.servlet.http.HttpSessionAttributeListener
Advantage of Observer Design Pattern in Java
Loose coupling between “observer“ and “Subject”.
The “Subject” only know the list of observers, it don’t care about how they have their implementation.
All the “observers“ are notified by “Subject” in a single event call
Disadvantage of Observer Design Pattern in Java
• Debugging becomes very difficult because flow of control is implicitly between observers and Subject.
• Another issue is Memory management because subject contains the reference of all the observers, If we do not unregister the observer object, it can create the memory issue.