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. 可能造成内存泄漏: 如果观察者没有被正确地移除,可能导致对观察者的引用一直存在,造成内存泄漏。

相关推荐
Amarantine、沐风倩✨18 分钟前
设计一个监控摄像头物联网IOT(webRTC、音视频、文件存储)
java·物联网·音视频·webrtc·html5·视频编解码·七牛云存储
路在脚下@1 小时前
spring boot的配置文件属性注入到类的静态属性
java·spring boot·sql
森屿Serien1 小时前
Spring Boot常用注解
java·spring boot·后端
Damon_X2 小时前
桥接模式(Bridge Pattern)
设计模式·桥接模式
苹果醋32 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
Hello.Reader3 小时前
深入解析 Apache APISIX
java·apache
菠萝蚊鸭3 小时前
Dhatim FastExcel 读写 Excel 文件
java·excel·fastexcel
旭东怪3 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
007php0073 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
∝请叫*我简单先生3 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl