Java实现数据更新和事件通知的观察者模式

 更新时间:2023年04月23日 10:47:55   作者:.番茄炒蛋  
Java观察者模式是一种行为型设计模式,用于实现对象间的一对多依赖关系。当一个对象的状态发生改变时,它的所有依赖对象都会收到通知并自动更新。观察者模式可以实现松耦合,增强了系统的可维护性和可拓展性

介绍

Java观察者模式(也称发布-订阅模式)是一种行为设计模式,用于对象之间的松散耦合,即当一个对象的状态发生变化时,其他依赖该对象的对象会被自动通知并作出相应的响应.

观察者模式有以下4种角色:

  • Subject(主题):被观察的对象,维护一个观察者列表,提供添加,删除观察者的方法,以及通知所有观察者的方法.
  • Observer(观察者):观察Subject的变化,当Subject变化时接收通知,进行相应的操作.
  • ConcreteSubject(具体主题):实现Subject接口,维护自己状态的变化,当状态变化时通知所有的观察者.
  • ConcreteObserver(具体观察者):实现Observer接口,具体实现在Subject发生变化时的响应方式.

实现

观察者接口

public interface Observer {
    /**
     * 通知观察者变化信息
     *
     * @param temperature
     * @param humidity
     */
    void update(float temperature,float humidity);
}

主题接口

public interface Subject {
    /**
     * 注册观察者
     *
     * @param observer
     */
    void registerObserver(Observer observer);
    /**
     * 删除观察者
     *
     * @param observer
     */
    void removeObserver(Observer observer);
    /**
     * 通知所有观察者
     */
    void notifyObservers();
}

具体主题

public class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    public WeatherData() {
        observers = new ArrayList<>();
    }
    /**
     * 注册观察者
     *
     * @param observer
     */
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
    /**
     * 删除观察者
     *
     * @param observer
     */
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    /**
     * 通知所有观察者
     */
    @Override
    public void notifyObservers() {
        observers.forEach(observer -> observer.update(temperature, humidity));
    }
    /**
     * 设置天气信息
     *
     * @param temperature
     * @param humidity
     */
    public void setMeasurements(float temperature, float humidity) {
        this.temperature = temperature;
        this.humidity = humidity;
        notifyObservers();
    }
}

具体观察者

public class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;
    public CurrentConditionsDisplay(Subject weatherData) {
        weatherData.registerObserver(this);
    }
    /**
     * 通知观察者变化信息
     *
     * @param temperature
     * @param humidity
     */
    @Override
    public void update(float temperature, float humidity) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }
    private void display() {
        System.out.println("温度:" + temperature + "℃;湿度:" + humidity + "%");
    }
}

测试

public class Demo {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
        weatherData.setMeasurements(35,53);
        weatherData.setMeasurements(32,48);
        weatherData.setMeasurements(26,44);
    }
}

在这个例子中,WeatherData是主题,CurrentConditonsDisplay是观察者.当WeatherData的数据发生变化时,它会通知已经注册的所有观察者进行相应的更新.在这个例子中CurrentConditionsDisplay观察者会展示当前的温度和湿度信息.

总结

Java观察者模式时一种常见的设计模式.该模式中,一个对象(被观察者)维护了一个观察者列表,当它自身发生改变时,会自动通知所有观察者做出相应的响应.

优点

  • 松耦合:被观察者和观察者之间是松耦合的关系,它们互相不知道对方的具体实现,只是通过接口进行通信,因此可以降低系统的耦合度,提高了系统的可扩展性.
  • 可重用性:观察者模式可以注册到不同的被观察者对象中,被观察者对象也可以有多个观察者对象,从而提高了代码的可重用性.
  • 开闭原则:观察者模式遵循开闭原则,因为在不修改被观察者和观察者的情况下,可以动态的添加或删除观察者对象.

缺点

  • 观察者模式可能会增加系统的复杂度和理解难度,因为观察者和被观察者之间存在多对多的关系,如果关系复杂,就会增加系统的复杂度.
  • 观察者模式在实现时可能会导致循环引用的问题,需要特别注意.

应用场景

  • 当一个对象的改变需要同时改变其他对象时,可以考虑使用观察者模式,例如实现GUI界面中的时间处理机制.
  • 当系统需要在运行时动态地将消息广播给其他对象时,可以考虑使用观察者模式,例如实现消息推送系统.
  • 当需要解耦合对象之间的关系时,可以考虑使用观察者模式,例如实现MVC模式中的数据视图分离.

到此这篇关于Java实现数据更新和事件通知的观察者模式的文章就介绍到这了,更多相关Java观察者模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java后端SSM框架图片上传功能实现方法解析

    Java后端SSM框架图片上传功能实现方法解析

    这篇文章主要介绍了Java后端SSM框架图片上传功能实现方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Java类获取Spring中bean的5种方式

    Java类获取Spring中bean的5种方式

    这篇文章主要为大家详细介绍了Java类获取Spring中bean的5种方式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • 浅析Spring中的循环依赖问题

    浅析Spring中的循环依赖问题

    这篇文章主要介绍了浅析Spring中的循环依赖问题,Spring 是利用了 三级缓存 来解决循环依赖的,其实现本质是通过提前暴露已经实例化但尚未初始化的 bean 来完成的,需要的朋友可以参考下
    2023-11-11
  • Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解

    Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解

    这篇文章主要介绍了Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 如何在Spring WebFlux的任何地方获取Request对象

    如何在Spring WebFlux的任何地方获取Request对象

    这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下
    2021-01-01
  • Spring Boot 入门教程

    Spring Boot 入门教程

    相信很多人都接触spring框架很长时间了,每次搭建spring框架的时候都需要配置好多的jar、xml,做很多繁琐重复的配置,稍微不留神就会出现各种各样的问题。今天给大家介绍一下如何利用Spring Boot快速的搭建一个简单的web应用
    2017-03-03
  • Java结合redis实现接口防重复提交

    Java结合redis实现接口防重复提交

    本文主要介绍了Java结合redis实现接口防重复提交,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Hystrix Dashboard断路监控仪表盘的实现详细介绍

    Hystrix Dashboard断路监控仪表盘的实现详细介绍

    这篇文章主要介绍了Hystrix Dashboard断路监控仪表盘的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-09-09
  • spring中@ComponentScan自动扫描并指定扫描规则

    spring中@ComponentScan自动扫描并指定扫描规则

    本文主要介绍了spring中@ComponentScan自动扫描并指定扫描规则,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Java String字符串和Unicode字符相互转换代码

    Java String字符串和Unicode字符相互转换代码

    这篇文章主要介绍了Java String字符串和Unicode字符相互转换代码,需要的朋友可以参考下
    2014-10-10

最新评论