OBSERVER
The Observer design pattern is a behavioral design pattern that establishes a one-to-many dependency between objects, so that when one object changes its state, all the dependent objects are automatically notified and updated. This is similar to a pub/sub model. The Subject is the one which needs to be observed by multiple Observers. When something changes in the subject, it notifies all the observers which can take appropriate actions.
OVERVIEW (UML)
Created using PlantUML.
Let’s imagine a scenario where we have a weather station that collects weather data (such as temperature, humidity, and pressure) and wants to notify multiple displays when the weather conditions change. To implement the Observer design pattern, we’ll create three main components: the Subject, the Observers, and the Concrete Subject.
CODE WALKTHROUGH
SUBJECT INTERFACE - THE THING TO BE OBSERVED
This is the interface that defines the methods for registering, removing, and notifying observers.
1
2
3
4
5
6
7
8
9
10
package com.designpattern;
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
OBSERVER - THE ONES WHICH NEED TO BE NOTIFIED WHEN THE SUBJECT CHANGES
This is the interface that defines the method to be called when the subject notifies the observers.
1
2
3
4
5
6
7
8
package com.designpattern;
public interface Observer {
void update(float temperature, float humidity, float pressure);
}
WEATHER STATION - SUBJECT IMPLEMENTATION
This is the class that implements the Subject interface and holds the current weather data.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.designpattern;
import java.util.ArrayList;
import java.util.List;
public class WeatherStation implements Subject {
List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherStation() {
observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
//Iterate over the list of observers and calls their update() method.
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
//update the measurements and call the notifyObserver() method
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
notifyObservers();
}
}
DISPLAY - OBSERVER IMPLEMENTATION
This will mimic an observer which needs to be notified when the subject (WeatherStation) get an update, in this case, the method setMeasurement() is called.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.designpattern;
public class Display implements Observer{
private String displayName;
public Display(String displayName) {
this.displayName = displayName;
}
@Override
public void update(float temperature, float humidity, float pressure) {
System.out.println("Notified: " + displayName);
System.out.println("Temperature: " + temperature);
System.out.println("Humidity: " + humidity);
System.out.println("Pressure: " + pressure);
System.out.println();
}
}
CLIENT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.demo;
import com.designpattern.Display;
import com.designpattern.WeatherStation;
public class App {
public static void main(String[] args) {
WeatherStation weatherStation = new WeatherStation();
Display display1 = new Display("display1");
Display display2 = new Display("display2");
weatherStation.registerObserver(display1);
weatherStation.registerObserver(display2);
weatherStation.setMeasurements(25.5f, 65.2f, 1013.2f);
weatherStation.removeObserver(display1);
weatherStation.setMeasurements(25.0f, 75.2f, 1017.2f);
}
}
OUTPUT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Notified: display1
Temperature: 25.5
Humidity: 65.2
Pressure: 1013.2
Notified: display2
Temperature: 25.5
Humidity: 65.2
Pressure: 1013.2
Notified: display2
Temperature: 25.0
Humidity: 75.2
Pressure: 1017.2