10.观察者模式

文章目录


一、介绍

观察者模式是一种行为设计模式,其中一个对象(称为主题)维护其依赖项(称为观察者)的列表,当主题的状态发生变化时,它通知所有的观察者,使得它们能够自动更新。

观察者模式主要涉及三个角色:

  1. 主题(Subject): 维护一组观察者,提供方法来添加和删除观察者,以及通知观察者状态变化的方法。

  2. 观察者(Observer): 定义一个更新接口,以便主题在状态变化时能够通知观察者。

  3. 具体主题(ConcreteSubject): 继承自主题,实现具体的业务逻辑,并在状态发生变化时通知观察者。

  4. 具体观察者(ConcreteObserver): 实现观察者接口,以便在接收到通知时能够执行相应的操作。

二、代码

结构图

场景

假设我们有一个气象站,气象站会定期更新温度,湿度和气压。我们希望设计一个系统,当气象站的数据更新时,所有注册的显示器(观察者)都能够自动更新显示。

代码

java 复制代码
// 主题接口:气象站
interface WeatherStation {
    void registerObserver(WeatherObserver observer);
    void removeObserver(WeatherObserver observer);
    void notifyObservers();
}
java 复制代码
// 观察者接口:显示器
interface WeatherObserver {
    void update(float temperature, float humidity, float pressure);
}
java 复制代码
// 具体主题:具体的气象站
class ConcreteWeatherStation implements WeatherStation {
    private List<WeatherObserver> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public ConcreteWeatherStation() {
        this.observers = new ArrayList<>();
    }

    @Override
    public void registerObserver(WeatherObserver observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(WeatherObserver observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (WeatherObserver observer : observers) {
            observer.update(temperature, humidity, pressure);
        }
    }

    // 模拟气象站数据更新
    public void setWeatherData(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        notifyObservers();
    }
}
java 复制代码
// 具体观察者1:温度显示器
class TemperatureDisplay implements WeatherObserver {
    @Override
    public void update(float temperature, float humidity, float pressure) {
        System.out.println("Temperature Display: Current Temperature = " + temperature);
    }
}

// 具体观察者2:湿度显示器
class HumidityDisplay implements WeatherObserver {
    @Override
    public void update(float temperature, float humidity, float pressure) {
        System.out.println("Humidity Display: Current Humidity = " + humidity);
    }
}
java 复制代码
// 客户端
public class ObserverPatternExample {
    public static void main(String[] args) {
        ConcreteWeatherStation weatherStation = new ConcreteWeatherStation();

        // 注册观察者
        WeatherObserver temperatureDisplay = new TemperatureDisplay();
        WeatherObserver humidityDisplay = new HumidityDisplay();
        weatherStation.registerObserver(temperatureDisplay);
        weatherStation.registerObserver(humidityDisplay);

        // 模拟气象站数据更新,观察者自动更新显示
        weatherStation.setWeatherData(25.5f, 60.0f, 1012.0f);

        // 移除一个观察者
        weatherStation.removeObserver(temperatureDisplay);

        // 模拟气象站数据更新,仅湿度显示器会更新
        weatherStation.setWeatherData(26.0f, 65.0f, 1010.5f);
    }
}

在客户端,我们创建了一个具体的气象站对象,并注册了温度显示器和湿度显示器作为观察者。随后,通过模拟气象站数据的更新,观察者自动更新了显示


总结

优点

  1. 松耦合: 观察者模式实现了目标和观察者之间的松耦合。主题(目标)和观察者之间相互独立,它们只是通过接口进行通信。

  2. 可扩展性: 新的观察者可以随时被加入到系统中,而无需修改主题的代码。这使得系统更容易扩展和维护。

  3. 通知机制: 主题发生变化时,会自动通知所有的观察者。这种通知机制使得观察者能够实时获取目标的最新状态。

缺点

  1. 可能引起性能问题: 如果观察者非常多,而且通知频繁,可能会影响性能。因为每个观察者都需要被通知,而且通知是同步的。

  2. 可能导致循环依赖: 当观察者之间存在相互依赖时,可能导致循环依赖的问题。这样的情况下,系统可能需要被重新设计。

  3. 可能造成内存泄漏: 如果观察者没有被正确地移除,可能导致对观察者的引用一直存在,造成内存泄漏。

相关推荐
Tech Synapse8 分钟前
Java循环创建对象内存溢出怎么解决
java·开发语言·jvm
IT·陈寒9 分钟前
Kotlin vs Java:深入解析两者之间的最新差异与优劣(全面指南)
java·python·kotlin
行动π技术博客20 分钟前
spring中IOC相关介绍
java·spring·rpc
吃青椒的小新30 分钟前
独一无二的设计模式——单例模式(Java实现)
java·后端·单例模式·设计模式
天才梦浪33 分钟前
开源租房项目
java·项目
杰哥在此1 小时前
Java面试题:解释跨站脚本攻击(XSS)的原理,并讨论如何防范
java·开发语言·面试·编程·xss
Czi橙1 小时前
玩玩快速冥(LeetCode50题与70题以及联系斐波那契)
java·算法·快速幂·斐波那契
青云交1 小时前
Java面试题--JVM大厂篇之深入了解G1 GC:大型Java应用的性能优化利器
java·jvm·性能优化·g1 gc适用的具体场景·g1 gc的特点·g1 gc的配置和调优示例·混合回收
Mero技术博客1 小时前
第三节:如何理解Spring的两个特性IOC和AOP(自学Spring boot 3.x第一天)
java·spring boot·spring
菠菜很好吃2 小时前
Java知识点大纲
java·jvm·spring