Design pattern - observer pattern

Posted by chimp1950 on Thu, 30 Dec 2021 12:22:53 +0100

preface

This paper briefly introduces a kind of design pattern, observer pattern

        (previous article) design pattern - Decorator Pattern_ Autumn rain - CSDN blog

catalogue

1, Definition and characteristics of observer model

2, Structure of observer model

3, Code example

1, Definition and characteristics of observer model

Definition of observer mode:

It means that there is a one to many dependency between multiple objects. When the state of an object changes, all objects that depend on it are notified and automatically updated. This mode is sometimes called publish subscribe mode and model view mode. It is an object behavior mode.

Features:

  1. It reduces the coupling relationship between the target and the observer, which is an abstract coupling relationship. Comply with the principle of dependency inversion.

  2. A trigger mechanism is established between the target and the observer.

2, Structure of observer model

When implementing observer mode, it should be noted that the specific target object and the specific observer object cannot be called directly, otherwise they will be closely coupled, which violates the object-oriented design principle. The main roles of the observer model are as follows.

        

Subject class: it saves all references to observer objects in an aggregation. Each topic can have any number of observers. The abstract topic provides an interface to add and delete any observer object

Observer class: Abstract observer. It defines an interface for all concrete observers and updates itself when notified of the subject

ConcreteSubject: for a specific topic, the relevant status is stored in the specific observer object. When the internal status of the specific topic changes, a notice is sent to all registered observers

ConcreteObserver: a concrete observer, which implements the update interface required by the abstract observer role, so as to coordinate its own state with the state of the subject

3, Code example

Now there is a demand that all websites need to subscribe to weather demand. We need to update and send weather information in time, and we can freely register or remove the websites we want to send, which can be realized in observer mode.

If we use the traditional mode to implement this case, there will be a problem, that is, if we want to modify the website, we may go back to change the code of the website class and the code of our operation to update data, which is not in line with our opening and closing principle. Therefore, we use the observer mode to implement it, because it is also a one to many dependency, There are many such cases in life, such as subscribing to magazines, etc.

The structure diagram is as follows:

Code example

Abstract target class Subject

        

package com.observerPattern.weatherCase;

/**
 * @author wang
 * @version 1.0
 * @packageName com.observerPattern.weatherCase
 * @className Subject
 * @date 2021/12/28 15:49
 * @Description Subject The abstract target class is implemented by the specific target
 */
public interface Subject {
    /**
     * @Date  2021/12/28 16:20
     * @Param
     * @param o
     * @Return void
     * @MetodName registerObserver
     * @Author wang
     * @Description Registered observer method
     */
    void registerObserver(Observer o);
    /**
     * @Date  2021/12/28 16:20
     * @Param
     * @param o
     * @Return void
     * @MetodName removeObserver
     * @Author wang
     * @Description Remove observer
     */
    void removeObserver(Observer o);
    /**
     * @Date  2021/12/28 16:20
     * @Param
     * @Return void
     * @MetodName notifyObservers
     * @Author wang
     * @Description Notify the observer
     */
    void notifyObservers();
}

Concrete target WeatherDate class

package com.observerPattern.weatherCase;

import java.util.ArrayList;

/**
 * @author wang
 * @version 1.0
 * @packageName com.observerPattern.weatherCase
 * @className WeatherDate
 * @date 2021/12/28 16:00
 * @Description It contains the latest weather data, which is a specific target and realizes the abstract target subject
 *  This class contains a collection of observers and is managed using the ArrayLis collection
 *  When the data is updated, it actively calls the ArrayList collection to notify each observer
 *
 */
public class WeatherDate implements Subject{
    private float temperature;
    private float pressure;
    private float humidity;
    private ArrayList<Observer> observers;


    /**
     * @Date  2021/12/28 16:10
     * @Param
     * @Return null
     * @MetodName WeatherDate
     * @Author wang
     * @Description Initializes the observer collection
     */
    public WeatherDate() {
        this.observers = new ArrayList<Observer>();
    }

    public float getTemperature() {
        return temperature;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    /**
     * @Date  2021/12/28 16:10
     * @Param
     * @Return void
     * @MetodName dateChange
     * @Author wang
     * @Description Call the notification method to push the updated data to each observer
     */
    public void dateChange() {
        notifyObservers();
    }

    /**
     * @Date  2021/12/28 16:11
     * @Param
     * @param temperature
     * @param pressure
     * @param humidity
     * @Return void
     * @MetodName setDate
     * @Author wang
     * @Description Update data
     */
    public void setDate(float temperature,float pressure,float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        dateChange();
    }


    /**
     * @Date  2021/12/28 16:11
     * @Param
     * @param o
     * @Return void
     * @MetodName registerObserver
     * @Author wang
     * @Description z Register an observer
     */
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    /**
     * @Date  2021/12/28 16:11
     * @Param
     * @param o
     * @Return void
     * @MetodName removeObserver
     * @Author wang
     * @Description Remove an observer
     */
    @Override
    public void removeObserver(Observer o) {
        if(observers.contains(o)) {
            observers.remove(o);
        }

    }

    /**
     * @Date  2021/12/28 16:12
     * @Param
     * @Return void
     * @MetodName notifyObservers
     * @Author wang
     * @Description Notify the observer
     */
    @Override
    public void notifyObservers() {
        for(int i = 0;i< observers.size();i++) {
            observers.get(i).update(this.temperature,this.pressure,this.humidity);
        }
    }
}

Abstract Observer:

package com.observerPattern.weatherCase;

/**
 * @author wang
 * @version 1.0
 * @packageName com.observerPattern.weatherCase
 * @className Observer
 * @date 2021/12/28 15:50
 * @Description Observer interface, method update, temperature, pressure, humidity, implemented by a specific observer
 */
public interface Observer {
    /**
     * @Date  2021/12/28 16:18
     * @Param
     * @param temperature
     * @param pressure
     * @param humidity
     * @Return void
     * @MetodName update
     * @Author wang
     * @Description
     */
    void update(float temperature,float pressure,float humidity);
}

Specific observer 1

        

package com.observerPattern.weatherCase;

/**
 * @author wang
 * @version 1.0
 * @packageName com.observerPattern.weatherCase
 * @className CurrentCondition
 * @date 2021/12/28 15:54
 * @Description A specific Observer class that represents the current weather conditions and implements the observer interface
 */
public class CurrentCondition implements Observer{

    private float temperature;
    private float pressure;
    private float humidity;

    /**
     * @Date  2021/12/28 15:58
     * @Param
     * @param temperature
     * @param pressure
     * @param humidity
     * @Return void
     * @MetodName update
     * @Author wang
     * @Description This method pushes the updated data to the observer and the observer prints it
     */
    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        display();
    }
    /**
     * @Date  2021/12/28 15:59
     * @Param
     * @Return void
     * @MetodName display
     * @Author wang
     * @Description This method displays the updated data
     */
    public void display() {
        System.out.println("The test shows the current temperature:" + temperature + "degree");
        System.out.println("The test shows the current pressure:" + pressure + "PA");
        System.out.println("The test shows the current humidity:" + humidity + "Rh");
    }
}

Specific observer 2:
        

package com.observerPattern.weatherCase;

/**
 * @author wang
 * @version 1.0
 * @packageName com.observerPattern.weatherCase
 * @className SinaNet
 * @date 2021/12/28 16:21
 * @Description Sina website as an observer
 */
public class SinaNet implements Observer{
    private float temperature;
    private float pressure;
    private float humidity;

    /**
     * @Date  2021/12/28 15:58
     * @Param
     * @param temperature
     * @param pressure
     * @param humidity
     * @Return void
     * @MetodName update
     * @Author wang
     * @Description This method pushes the updated data to the observer and the observer prints it
     */
    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        display();
    }
    /**
     * @Date  2021/12/28 15:59
     * @Param
     * @Return void
     * @MetodName display
     * @Author wang
     * @Description This method displays the updated data
     */
    public void display() {
        System.out.println("=======Sina website=======");
        System.out.println("Sina displays the current temperature:" + temperature + "degree");
        System.out.println("Sina displays the current pressure:" + pressure + "PA");
        System.out.println("Display current humidity:" + humidity + "Rh");
    }
}

Client test class

        

package com.observerPattern.weatherCase;

/**
 * @author wang
 * @version 1.0
 * @packageName com.observerPattern.weatherCase
 * @className ClientTest
 * @date 2021/12/28 16:12
 * @Description Client test code, test observer mode
 */
public class ClientTest {
    public static void main(String[] args) {

        //Create a weatherDate target
        WeatherDate weatherDate = new WeatherDate();

        //Create an observer
        CurrentCondition currentCondition = new CurrentCondition();

        //Register an observer
        weatherDate.registerObserver(currentCondition);

        //Register Sina
        SinaNet sinaNet = new SinaNet();
        weatherDate.registerObserver(sinaNet);

        //Test update
        System.out.println("Notify observers");
        weatherDate.setDate(3,65,12);

        //Test removal
        weatherDate.removeObserver(currentCondition);

        System.out.println("========================");
        System.out.println("Second update");
        weatherDate.setDate(6,88,16);
    }
}
/*
Notify observers
 The test shows that the current temperature is 3.0 degrees
 The test shows that the current pressure is 65.0 PA
 The test shows that the current humidity is 12.0Rh
=======Sina website=======
Sina displays the current temperature: 3.0 degrees
 Sina display current pressure: 65.0 pa
 Sina display current humidity: 12.0Rh
========================
Second update
=======Sina website=======
Sina shows that the current temperature is 6.0 degrees
 Sina display current pressure: 88.0 pa
 Sina display current humidity: 16.0Rh
 */

The advantage is that if we add a new website, we can directly add an observer class without modifying the code

As well as deletion and registration are independent.  

Reference: big talk design mode

Topics: Java Design Pattern architecture