Describe the Observer design pattern and provide an example of its usage.

Software Design Patterns Questions Medium



46 Short 30 Medium 40 Long Answer Questions Question Index

Describe the Observer design pattern and provide an example of its usage.

The Observer design pattern is a behavioral design pattern that allows objects to establish a one-to-many dependency relationship, where multiple observers are notified automatically when the state of a subject object changes. In this pattern, the subject object maintains a list of observers and notifies them whenever there is a change in its state.

The Observer pattern consists of the following key components:
1. Subject: It is the object that maintains a list of observers and provides methods to add, remove, or notify observers.
2. Observer: It is the interface or abstract class that defines the update method, which is called by the subject to notify the observer about the state change.
3. ConcreteSubject: It is the concrete implementation of the subject interface. It maintains the state and sends notifications to the registered observers.
4. ConcreteObserver: It is the concrete implementation of the observer interface. It registers itself with the subject and receives notifications when the subject's state changes.

Example:
Let's consider a scenario of a weather monitoring system. We have a WeatherStation object that measures temperature, humidity, and pressure. We want to notify multiple displays (observers) whenever there is a change in the weather conditions.

First, we define the Observer interface with an update method:
```
interface Observer {
void update(float temperature, float humidity, float pressure);
}
```

Next, we define the Subject interface with methods to register, remove, and notify observers:
```
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
```

Then, we implement the ConcreteSubject class, WeatherStation, which maintains the state and notifies the observers:
```
class WeatherStation implements Subject {
private List observers;
private float temperature;
private float humidity;
private float pressure;

public WeatherStation() {
observers = new ArrayList<>();
}

public void registerObserver(Observer observer) {
observers.add(observer);
}

public void removeObserver(Observer observer) {
observers.remove(observer);
}

public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}

public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
notifyObservers();
}
}
```

Finally, we implement the ConcreteObserver class, Display, which receives the notifications and displays the weather conditions:
```
class Display implements Observer {
private float temperature;
private float humidity;
private float pressure;

public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}

private void display() {
System.out.println("Current conditions: " + temperature + "F degrees, " + humidity + "% humidity, " + pressure + " pressure");
}
}
```

Now, we can create instances of WeatherStation and Display, register the display as an observer, and update the weather conditions:
```
WeatherStation weatherStation = new WeatherStation();
Display display = new Display();
weatherStation.registerObserver(display);

weatherStation.setMeasurements(75.5f, 60.2f, 30.1f);
```

In this example, the WeatherStation acts as the subject, while the Display acts as the observer. The WeatherStation notifies the Display whenever there is a change in the weather conditions, and the Display updates and displays the new conditions.