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

相关推荐
可乐加.糖2 分钟前
一篇关于Netty相关的梳理总结
java·后端·网络协议·netty·信息与通信
s9123601015 分钟前
rust 同时处理多个异步任务
java·数据库·rust
9号达人5 分钟前
java9新特性详解与实践
java·后端·面试
cg50179 分钟前
Spring Boot 的配置文件
java·linux·spring boot
啊喜拔牙17 分钟前
1. hadoop 集群的常用命令
java·大数据·开发语言·python·scala
anlogic1 小时前
Java基础 4.3
java·开发语言
非ban必选1 小时前
spring-ai-alibaba第七章阿里dashscope集成RedisChatMemory实现对话记忆
java·后端·spring
A旧城以西1 小时前
数据结构(JAVA)单向,双向链表
java·开发语言·数据结构·学习·链表·intellij-idea·idea
杉之2 小时前
选择排序笔记
java·算法·排序算法
Naive_72 小时前
蓝桥杯准备(前缀和差分)
java·职场和发展·蓝桥杯