Observer Design Pattern Example
Consider a scenario where you have a weather monitoring system. Different parts of your application need to be updated when the weather conditions change.
Challenges or difficulties while implementing this system without Observer Design Pattern
- Components interested in weather updates would need direct references to the weather monitoring system, leading to tight coupling.
- Adding or removing components that react to weather changes requires modifying the core weather monitoring system code, making it hard to maintain.
How Observer Pattern helps to solve above challenges?
The Observer Pattern helps decouple the weather monitoring system from the components interested in weather updates. Each component can register as an observer, and when the weather changes, the observers are notified. This way, adding or removing components doesn’t affect the weather monitoring system.
Below is the code of above problem statement using Observer Pattern:
1. Subject
- The “
Subject"
interface outlines the operations a subject (like “WeatherStation"
) should support. "addObserver"
and “removeObserver"
are for managing the list of observers."notifyObservers"
is for informing observers about changes.
Java
public interface Subject { void addObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); } |
2. Observer
- The “
Observer"
interface defines a contract for objects that want to be notified about changes in the subject (“WeatherStation"
in this case). - It includes a method “
update"
that concrete observers must implement to receive and handle updates.
Java
public interface Observer { void update(String weather); } |
3. ConcreteSubject(WeatherStation)
"WeatherStation"
is the concrete subject implementing the “Subject"
interface.- It maintains a list of observers (“
observers"
) and provides methods to manage this list. "notifyObservers"
iterates through the observers and calls their “update"
method, passing the current weather."setWeather"
method updates the weather and notifies observers of the change.
Java
import java.util.ArrayList; import java.util.List; public class WeatherStation implements Subject { private List<Observer> observers = new ArrayList<>(); private String weather; @Override public void addObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(weather); } } public void setWeather(String newWeather) { this .weather = newWeather; notifyObservers(); } } |
4. ConcreteObserver(PhoneDisplay)
"PhoneDisplay"
is a concrete observer implementing the “Observer"
interface.- It has a private field
weather
to store the latest weather. - The “
update"
method sets the new weather and calls the “display"
method. "display"
prints the updated weather to the console.
Java
public class PhoneDisplay implements Observer { private String weather; @Override public void update(String weather) { this .weather = weather; display(); } private void display() { System.out.println( "Phone Display: Weather updated - " + weather); } } |
5. ConcreteObserver(TVDisplay)
"TVDisplay"
is another concrete observer similar to “PhoneDisplay"
.- It also implements the “
Observer"
interface, with a similar structure to “PhoneDisplay"
.
Java
/*package whatever //do not write package name here */ import java.io.*; class GFG { public static void main (String[] args) { System.out.println( "GFG!" ); } } |
6. Usage
- In “
WeatherApp"
, a “WeatherStation"
is created. - Two observers (“
PhoneDisplay"
and “TVDisplay"
) are registered with the weather station using “addObserver"
. - The “
setWeather"
method simulates a weather change to “Sunny,” triggering the “update"
method in both observers. - The output shows how both concrete observers display the updated weather information.
Java
public class WeatherApp { public static void main(String[] args) { WeatherStation weatherStation = new WeatherStation(); Observer phoneDisplay = new PhoneDisplay(); Observer tvDisplay = new TVDisplay(); weatherStation.addObserver(phoneDisplay); weatherStation.addObserver(tvDisplay); // Simulating weather change weatherStation.setWeather( "Sunny" ); // Output: // Phone Display: Weather updated - Sunny // TV Display: Weather updated - Sunny } } |
Complete code for the above example
Below is the complete code for the above example:
Java
import java.util.ArrayList; import java.util.List; // Observer Interface interface Observer { void update(String weather); } // Subject Interface interface Subject { void addObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); } // ConcreteSubject Class class WeatherStation implements Subject { private List<Observer> observers = new ArrayList<>(); private String weather; @Override public void addObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(weather); } } public void setWeather(String newWeather) { this .weather = newWeather; notifyObservers(); } } // ConcreteObserver Class class PhoneDisplay implements Observer { private String weather; @Override public void update(String weather) { this .weather = weather; display(); } private void display() { System.out.println( "Phone Display: Weather updated - " + weather); } } // ConcreteObserver Class class TVDisplay implements Observer { private String weather; @Override public void update(String weather) { this .weather = weather; display(); } private void display() { System.out.println( "TV Display: Weather updated - " + weather); } } // Usage Class public class WeatherApp { public static void main(String[] args) { WeatherStation weatherStation = new WeatherStation(); Observer phoneDisplay = new PhoneDisplay(); Observer tvDisplay = new TVDisplay(); weatherStation.addObserver(phoneDisplay); weatherStation.addObserver(tvDisplay); // Simulating weather change weatherStation.setWeather( "Sunny" ); // Output: // Phone Display: Weather updated - Sunny // TV Display: Weather updated - Sunny } } |
Output
Phone Display: Weather updated - Sunny TV Display: Weather updated - Sunny |
Observer Design Pattern
The Observer Design Pattern is a behavioral design pattern that defines a one-to-many dependency between objects so that when one object (the subject) changes state, all its dependents (observers) are notified and updated automatically.
Important Topics for the Observer Design Pattern
- What is the Observer Design Pattern?
- Real-world analogy of the Observer Design Pattern
- Components of Observer Design Pattern
- Observer Design Pattern example
- When to use the Observer Design Pattern?
- When not to use the Observer Design Pattern?