Modo observador (20)

Cree en ti mismo, por favor cree en ti mismo

El capítulo anterior presentó brevemente el modo iterador (19), si no lo ha leído, mire el capítulo anterior

1. Modo observador

Consulte la introducción del patrón de observador en el tutorial para principiantes: https://www.runoob.com/design-pattern/observer-pattern.html

Cuando existe una relación de uno a muchos entre objetos, se utiliza el patrón de observador (Observer Pattern).

Por ejemplo, cuando se modifica un objeto, se notifica automáticamente a los objetos que dependen de él. El patrón del observador es un patrón de comportamiento.

1.1 Introducción

Intención: defina una relación de dependencia de uno a muchos entre objetos. Cuando el estado de un objeto cambia, todos los objetos que dependen de él serán notificados y actualizados automáticamente.

Principalmente para resolver: el problema de notificar a otros objetos del cambio de estado de un objeto, y teniendo en cuenta la facilidad de uso y el bajo acoplamiento para garantizar un alto grado de colaboración.

Cuándo usar: cuando cambia el estado de un objeto (objeto objetivo), todos los objetos dependientes (objetos observadores) serán notificados y se transmitirán notificaciones.

Cómo solucionarlo: Usando tecnología orientada a objetos, esta dependencia puede debilitarse.

Código clave: hay un ArrayList en la clase abstracta para almacenar observadores.

Ejemplo de aplicación: 1. Durante la subasta, el subastador observa la oferta más alta y luego notifica a otros postores para que hagan una oferta. 2. En Journey to the West, Wukong le rogó al Bodhisattva que sometiera al niño rojo, y el Bodhisattva roció mucha agua, y atrajo a una tortuga vieja. Esta tortuga era el observador, y observó la acción del Bodhisattva rociando agua. .

Ventajas: 1. El observador y lo observado están acoplados de forma abstracta. 2. Establecer un mecanismo de activación.

Desventajas:
1. Si un objeto observado tiene muchos observadores directos e indirectos, llevará mucho tiempo notificar a todos los observadores.
2. Si existe una dependencia circular entre el observador y el objetivo de observación, el objetivo de observación activará una llamada circular entre ellos, lo que puede causar que el sistema se bloquee.
3. El modo de observador no tiene un mecanismo correspondiente para que el observador sepa cómo cambia el objeto objetivo observado, pero solo sabe que el objetivo observado ha cambiado.

Escenas a utilizar:

  • Un modelo abstracto tiene dos aspectos, uno de los cuales depende del otro. Encapsular estos aspectos en objetos separados permite cambiarlos y reutilizarlos de forma independiente.
  • El cambio de un objeto hará que uno o más objetos cambien, y no se sabe cuántos objetos cambiarán, lo que puede reducir el acoplamiento entre objetos.
  • Un objeto debe notificar a otros objetos sin saber quiénes son esos objetos.
  • Es necesario crear una cadena de activación en el sistema. El comportamiento del objeto A afectará al objeto B, y el comportamiento del objeto B afectará al objeto C... Puede utilizar el modo observador para crear un mecanismo de activación de cadena.

Notas: 1. JAVA ya tiene clases de soporte para el modo observador. 2. Evite las referencias circulares. 3. Si se ejecuta secuencialmente, un cierto error del observador hará que el sistema se atasque, y generalmente se usa el método asíncrono.


rol de composición específico relación
rol de observador abstracto Observador Defina una interfaz para que todos los observadores concretos se actualicen cuando el sujeto lo notifique
rol de observador específico Baidu, Sina, Usuario Implemente la interfaz de actualización requerida por el rol de observador abstracto, mientras coordina su propio estado con el estado del dibujo
rol de observador abstracto Sujeto Un sujeto abstracto que mantiene todas las referencias a objetos observadores en una colección.
Rol de observador específico WeatherDataSubject Un tema específico, cuando cambia el estado interno del tema colectivo, se notifica a todos los observadores registrados

imagen-20230615184354714

2. Instancia de observador

como observar el tiempo

2. Una entidad objeto observada Clima

@Data
@Builder
public class Weather {
    
    
    /**
      温度, 气压, 湿度
     */
    private float temperature;
    private float pressure;
    private float humidity;
}

2.2 Observador abstracto Observador

public interface Observer {
    
    

    public void update (Weather weather);
}

2.3 Implementación del observador concreto

2.3.1 Sitio web de Baidu

@Slf4j
public class BaiDu implements Observer{
    
    
    private Weather weather ;
    @Override
    public void update(Weather weather) {
    
    
        this.weather = weather;
        display();
    }

    public void display (){
    
    
        if (weather == null) {
    
    
            return ;
        }
        log.info(">>>>>>>>>>>>>百度网站获取到天气数据,进行个性化操作");
        log.info(">>>温度: {}, 气压: {}, 湿度: {}", weather.getTemperature(),weather.getPressure(),
                weather.getHumidity());
    }

}

2.3.2 Sitio web de Sina

@Slf4j
public class Sina implements Observer{
    
    
    private Weather weather ;
    @Override
    public void update(Weather weather) {
    
    
        this.weather = weather;
        display();
    }

    public void display (){
    
    
        if (weather == null) {
    
    
            return ;
        }
        log.info(">>>>>>>>>>>>>新浪网站获取到天气数据,进行个性化操作");
        log.info(">>>温度: {}, 气压: {}, 湿度: {}", weather.getTemperature(),weather.getPressure(),
                weather.getHumidity());
    }

}

2.3.3 Suscriptores

@Slf4j
public class User implements Observer{
    
    
    private Weather weather ;
    @Override
    public void update(Weather weather) {
    
    
        this.weather = weather;
        display();
    }

    public void display (){
    
    
        if (weather == null) {
    
    
            return ;
        }
        log.info(">>>>>>>>>>>>>订阅用户获取到天气数据,进行个性化操作");
        log.info(">>>温度: {}, 气压: {}, 湿度: {}", weather.getTemperature(),weather.getPressure(),
                weather.getHumidity());
    }

}

2.4 Sujeto observador abstracto

public interface Subject {
    
    
    public void registerObserver(Observer observer);

    public void remove (Observer observer);

    public void notifyObservers();
}

2.5 Implementación del observador concreto

@Slf4j
public class WeatherDataSubject implements Subject{
    
    
    private List<Observer> observerList = new ArrayList<>();
    private Weather weather;
    @Override
    public void registerObserver(Observer observer) {
    
    
        observerList.add(observer);
    }

    @Override
    public void remove(Observer observer) {
    
    
        observerList.remove(observer);
    }

    @Override
    public void notifyObservers() {
    
    
        for (Observer observer : observerList) {
    
    
            observer.update(this.weather);
        }
    }

    public void setWeather(Weather weather) {
    
    
        this.weather = weather;
        dataChange();
    }

    public void dataChange() {
    
    
        // 更新后,数据发生了改变。
        log.info("获取到了最新的数据: {}", this.weather);
        notifyObservers();
    }
}

2.6 Llamada de cliente

  @Test
    public void oneTest() {
    
    
        WeatherDataSubject weatherDataSubject = new WeatherDataSubject();
        weatherDataSubject.registerObserver(new BaiDu());
        weatherDataSubject.registerObserver(new Sina());

        // 设置数据
        weatherDataSubject.setWeather(
                Weather.builder()
                        .temperature(35.0f)
                        .pressure(20.0f)
                        .humidity(30.f)
                        .build()
        );
        User user = new User();
        // 再添加个数据
        weatherDataSubject.registerObserver(user);

        weatherDataSubject.setWeather(
                Weather.builder()
                        .temperature(30.0f)
                        .pressure(21.0f)
                        .humidity(32.f)
                        .build()
        );


        weatherDataSubject.remove(user);


        weatherDataSubject.setWeather(
                Weather.builder()
                        .temperature(32.0f)
                        .pressure(22.0f)
                        .humidity(33.f)
                        .build()
        );

    }

imagen-20230615185146367

3. Java implementa el patrón observador

En el lenguaje Java, el procesamiento del observador se puede realizar a través de Observer(Observer) Observable(Subject)

3. Un observador concreto y un observador abstracto

@Slf4j
public class NewUser implements Observer {
    
    
    private String name;
    public NewUser(String name) {
    
    
        this.name = name;
    }
    @Override
    public void update(Observable o, Object arg) {
    
    
        log.info("{} 观察到信息发生了变化 {}", name,arg);
    }
}

3.2 Observación concreta y observación abstracta

public class NewWeatherDataSubject extends Observable {
    
    
    private Weather weather;

    public NewWeatherDataSubject (Weather weather) {
    
    
        this.weather = weather;
    }

    public void setWeather(Weather weather) {
    
    
        this.weather = weather;
        // 改变了
        super.setChanged();
        super.notifyObservers(weather);
    }
}

3. Tres llamadas de clientes

@Test
    public void twoTest() {
    
    
        Weather weather = Weather.builder()
                .temperature(32.0f)
                .pressure(22.0f)
                .humidity(33.f)
                .build();
        NewWeatherDataSubject newWeatherDataSubject = new NewWeatherDataSubject(weather);
        newWeatherDataSubject.addObserver(new NewUser("用户1"));
        newWeatherDataSubject.addObserver(new NewUser("用户2"));
        newWeatherDataSubject.addObserver(new NewUser("用户3"));
        log.info("温度发生改变");
        weather.setTemperature(34.f);
        newWeatherDataSubject.setWeather(weather);
        log.info("温度再次发生改变");
        weather.setTemperature(30.f);
        newWeatherDataSubject.setWeather(weather);
    }

imagen-20230615185508442


El código de este capítulo se encuentra en github:


https://github.com/yuejianli/DesignPattern/tree/develop/Observer


Gracias por mirar, si te gusta, por favor sígueme, gracias de nuevo!!!

Supongo que te gusta

Origin blog.csdn.net/yjltx1234csdn/article/details/131234085
Recomendado
Clasificación