Record of Head First design mode -- observer mode

Posted by HuggieBear on Sun, 26 Dec 2021 16:32:43 +0100

The observer pattern defines a one to many dependency. When an object changes state, all its dependents will receive notification and update data.

For example, we commonly set up monitoring, button Setonclicklistener is also a kind of observer.

Core concerns

The observer and the observed are loosely coupled. The observed only needs to know that the observers have implemented a unified interface and provided update methods. As long as the interface remains unchanged, changing the content of either party will not affect the other party.

If the list of observers is held by the observed, all observers in the list will be notified in case of data change. Pay attention to remove the observers in time when canceling the observation to avoid memory leakage

Story scene of weather station

Company X cooperates with the meteorological observatory. The meteorological observatory will provide a WeatherData object, which will track the current weather conditions, temperature, humidity and air pressure. Company X is required to provide a system that can access different bulletin boards to display data. Any third party company is required to create bulletin boards to access and display the data of the meteorological observatory.

We define the subject interface (observed interface), and declare the methods of adding observers, removing observers, and notifying changes. At the same time, define an observer interface and declare an updated method.

There is a display interface in the figure. Considering that different bulletin boards display different styles and effects, this interface is available here.

interface Observer {
    void update(float temp, float humidity, float pressure);
}


interface DisplayElement {
    void display(float temp, float h, float p);
}


public interface Subject {
    void registObserver(Observer observer);
    void removeOBserver(Observer observer);
    void notifyOBservers();
}

Data monitoring object

class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

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

    @Override
    public synchronized void registObserver(Observer observer) {
        if (observers.contains(observer)) {
            return;
        }
        observers.add(observer);
    }

    @Override
    public synchronized void removeOBserver(Observer observer) {
        if (!observers.contains(observer)) {
            return;
        }
        observers.remove(observer);
    }

    @Override
    public void notifyOBservers() {
        for (Observer o : observers) {
            o.update(temperature, humidity, pressure);
        }
    }

    private void measurementChanged() {
        notifyOBservers();
    }

    public void setMeasurements(float t, float m, float p) {
        this.temperature = t;
        this.humidity = m;
        this.pressure = p;
        measurementChanged();

    }
}

a bulletin board

class CurrentConditionDisplay implements Observer, DisplayElement {
    private WeatherData mWeatherData;

    public CurrentConditionDisplay(WeatherData weatherData) {
        this.mWeatherData = weatherData;
        weatherData.registObserver(this);
    }

    @Override
    public void display(float temp, float h, float p) {
        System.out.println("Bulletin board display data: temperature:" + temp + "   Humidity is:" + h + "   The air pressure is:" + p);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        //Got the data,
        System.out.println("The bulletin board was notified of the data update");
        display(temp, humidity, pressure);
    }

    public void destroy() {
        mWeatherData.removeOBserver(this);
        mWeatherData = null;
    }
}
WeatherData weatherData = new WeatherData();
CurrentConditionDisplay currentConditionDisplay = new CurrentConditionDisplay(weatherData);

weatherData.setMeasurements(30f, 20f, 1.0f);

 

The observer mode is built in java. However, the Observable built in java is a class. In the case of java single inheritance, once the Observable class is inherited, other classes cannot be inherited. In addition, the internal notifyObservers method will send a notification only when the state changed is true, and the setChanged method is protected. If it is not its subclass, it cannot call to change the state. It's a pit.

Topics: Design Pattern