Observer Design Pattern
Saji Kuttan
Senior Software Engineer @HCL TECH | Ex-Infoscion | Building Secure and Scalable Software's | Full Stack Developer
The Observer Design Pattern is a behavioral pattern where an object (called the subject) maintains a list of its dependents (called observers) and notifies them of any state changes, typically by calling one of their methods. This is useful when one object needs to automatically update several others when its state changes, ensuring consistency across related objects.
Observable Design Pattern Example
Let's consider an example of a Weather Station that notifies multiple displays (like a Phone Display, Window Display, or Web Display) whenever the temperature or other weather conditions change.
Key Components:
1. Subject (WeatherStation): The subject is an interface or abstract class that provides methods to attach, detach, and notify observers.
2. Concrete Subject (ConcreteWeatherStation): This class implements the subject interface and keeps track of the state (temperature). It notifies observers when the state changes.
3. Observer (WeatherDisplay): The observer interface defines the method that will be called when the subject notifies its observers.
4. Concrete Observers (PhoneDisplay, WindowDisplay, WebDisplay): These are specific observers that implement the observer interface and respond to changes in the subject.
Example:
Step 1: Define the WeatherStation interface (Subject)
```java
import java.util.ArrayList;
import java.util.List;
// The Subject Interface
public interface WeatherStation {
void addObserver(WeatherDisplay observer);
void removeObserver(WeatherDisplay observer);
void notifyObservers();
}
```
Step 2: Define the WeatherDisplay interface (Observer)
```java
// The Observer Interface
public interface WeatherDisplay {
void update(float temperature);
}
```
Step 3: Create the ConcreteWeatherStation class (Concrete Subject)
```java
// The Concrete Subject
public class ConcreteWeatherStation implements WeatherStation {
private List<WeatherDisplay> observers;
private float temperature;
public ConcreteWeatherStation() {
this.observers = new ArrayList<>();
}
// Register an observer
@Override
public void addObserver(WeatherDisplay observer) {
observers.add(observer);
}
// Remove an observer
@Override
public void removeObserver(WeatherDisplay observer) {
observers.remove(observer);
}
// Notify all observers about the temperature change
@Override
public void notifyObservers() {
for (WeatherDisplay observer : observers) {
observer.update(temperature);
}
}
// Update the temperature and notify observers
public void setTemperature(float temperature) {
this.temperature = temperature;
notifyObservers();
}
}
```
Step 4: Create the PhoneDisplay, WindowDisplay, and WebDisplay classes (Concrete Observers)
```java
// Phone Display - Concrete Observer
public class PhoneDisplay implements WeatherDisplay {
@Override
public void update(float temperature) {
System.out.println("Phone Display: Current temperature is " + temperature + "°C");
}
}
// Window Display - Concrete Observer
领英推荐
public class WindowDisplay implements WeatherDisplay {
@Override
public void update(float temperature) {
System.out.println("Window Display: Current temperature is " + temperature + "°C");
}
}
// Web Display - Concrete Observer
public class WebDisplay implements WeatherDisplay {
@Override
public void update(float temperature) {
System.out.println("Web Display: Current temperature is " + temperature + "°C");
}
}
```
Step 5: Demonstrate the Observer Pattern
```java
public class Main {
public static void main(String[] args) {
// Create the weather station (subject)
ConcreteWeatherStation weatherStation = new ConcreteWeatherStation();
// Create displays (observers)
WeatherDisplay phoneDisplay = new PhoneDisplay();
WeatherDisplay windowDisplay = new WindowDisplay();
WeatherDisplay webDisplay = new WebDisplay();
// Register observers with the subject
weatherStation.addObserver(phoneDisplay);
weatherStation.addObserver(windowDisplay);
weatherStation.addObserver(webDisplay);
// Simulate temperature change
weatherStation.setTemperature(25.0f);
System.out.println("Temperature changed!");
// Another temperature update
weatherStation.setTemperature(30.0f);
System.out.println("Temperature changed again!");
}
}
```
Output:
```
Phone Display: Current temperature is 25.0°C
Window Display: Current temperature is 25.0°C
Web Display: Current temperature is 25.0°C
Temperature changed!
Phone Display: Current temperature is 30.0°C
Window Display: Current temperature is 30.0°C
Web Display: Current temperature is 30.0°C
Temperature changed again!
```
Explanation:
1. WeatherStation Interface (Subject): It defines the methods to register, remove, and notify observers.
2. ConcreteWeatherStation (Concrete Subject): This class implements the subject interface, maintains the list of observers, and notifies them whenever the temperature changes.
3. WeatherDisplay Interface (Observer): This interface defines the update() method that all observers must implement.
4. Concrete Observers (PhoneDisplay, WindowDisplay, WebDisplay): Each of these classes implements the update() method to display the temperature.
Workflow:
- Observers (PhoneDisplay, WindowDisplay, WebDisplay) register with the WeatherStation (subject).
- Whenever the temperature changes, the WeatherStation calls notifyObservers() to update all registered observers by calling their update() method with the latest temperature.
Advantages:
- Loose Coupling: The subject and observers are loosely coupled. The subject knows nothing about the concrete observers, and the observers can be added or removed without modifying the subject.
- Multiple Observers: A single subject can notify multiple observers, making it suitable for scenarios where multiple components need to react to changes in one object.
Use Cases:
- Event Systems: Notifications like user activity in applications.
- MVC Architecture: The view observes changes in the model.
- Push Notifications: When an event occurs, all subscribers are notified automatically.
Conclusion:
The Observer Design Pattern is ideal for scenarios where multiple objects need to stay in sync with the state of another object. By using this pattern, the WeatherStation and its displays can maintain consistency without being tightly coupled, allowing for flexibility in adding new observers in the future.
#SoftwareDesign #StatefulPattern #Architecture #DesignPatterns #Developers #ProgrammingTips #observerdesignpattern #JAVA #C #CPP #JAVASCRIPT #Python