Software Design Patterns Questions Medium
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
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.