[Design Pattern] Observer pattern

Following the Strategy pattern last time, I am going to organize the Observer pattern this time.

This article summarizes and organizes the contents of the Head First Design Patterns(By Eric Freeman, Elisabeth Freeman, Elisabeth) book.

Photo by Pavan Trikutam on Unsplash

Definitions for Observer pattern

The Observer pattern defines one-to-many dependencies in such a way that when an object changes its history, it contacts other objects that depend on it and automatically updates the content.

I like to talk about conclusions first and explain them in detail.
I will explain in detail the above definition from now on.

1. Relationship of objects in the Observer pattern

The book describes Observer pattern by taking newspaper subscriptions as an example. I think this example is very good.
As anyone who has subscribed to the newspaper knows, there are two main relationships here. They are newspaper publishers and subscribers.

As can be seen from the above definition, there is a one-to-many relationship in the observer pattern, which also forms a one-to-many relationship with newspaper publishers and subscribers.

In the Observer pattern, objects corresponding to newspaper publishers are called a Subject object and subscribers are called Observer objects.

2. How to Implement Observer Patterns

In the article in Strategy pattern last time, I told them that they should be programmed according to the interface, not the implementation.

It applies equally to the Observer pattern.

The reason for doing this is to loosen the relationship between objects.

Loose coupling of objects allows building flexible object-oriented systems by minimizing interdependencies between objects.

3. Example

When there is a program that displays the measurement of weather changes in various ways, it is implemented in Observer pattern as follows. Here, the weather measurement becomes a subject and the objects that mark it become an Observer.

public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
public interface Observer {
public void update(float temp, float humidity, float pressure);
}
public interface DisplayElement {
public void display();
}
import java.util.ArrayList;public class WeatherData implements Subject {
private ArrayList<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<Observer>();
}

public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
public void notifyObservers() {
for (int i = 0; i < observers.size(); i++) {
Observer observer = (Observer) observers.get(i);
observer.update(temperature, humidity, pressure);
}
}
public void measurementsChanged() {
notifyObservers();
}

public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}

public void display() {
System.out.println(
"current conditions: "
+ temperature
+ "F degrees and "
+ humidity
+ "% humidity"
);
}
}
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currerntDisplay =
new CurrentConditionsDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
}
}

When this is implemented, the results are as follows.

Current conditions: 80.0F degrees and 65.0% humidity

In this example, it is possible to register as many Observer objects as needed and implement them for display in different ways.

If you want to update the weather, simply call the notifyObservers method of the weatherData instance. This will change the data for all Observer objects that are subscribing to the weatherData instance.

It is also possible to update only the desired changes in the Observer, rather than making all changes to the Observer. Java’s internal library supports this, and please refer to the book below for details.

In the example introduced, all the Observer(s) will update the changes in the subject’s data. However, the Observer can only be updated for the desired changes and is supported by the Java internal library. Please refer to the book introduced for details.

I love Programming 🧑🏻‍💻 https://github.com/Jay-flow