首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >深入理解观察者模式(Observer Pattern)

深入理解观察者模式(Observer Pattern)

作者头像
GeekLiHua
发布2025-01-21 14:43:07
发布2025-01-21 14:43:07
3120
举报
文章被收录于专栏:JavaJava

深入理解观察者模式(Observer Pattern)

简介:

观察者模式是一种行为设计模式,它允许对象(称为观察者)订阅另一个对象(称为主题)的状态变化。当主题状态发生改变时,观察者会被通知并进行相应的更新。

为什么使用观察者模式?

在现实生活中,我们经常会遇到这样的情况:当一个对象的状态发生改变时,其他对象也需要做出相应的变化。观察者模式提供了一种松耦合的方式来实现这种通信机制,使得主题和观察者之间的依赖关系更加灵活。

核心概念
  • 主题(Subject): 主题是被观察的对象,它会维护一组观察者,并提供方法来添加、删除和通知观察者。
  • 观察者(Observer): 观察者是订阅主题状态变化的对象,当主题状态发生改变时,观察者会接收到通知并执行相应的更新操作。
观察者模式的结构
  • Subject(主题):
    • 注册和移除观察者的方法
    • 通知观察者的方法
  • Observer(观察者):
    • 更新方法,用于接收主题状态的变化

观察者模式的 UML 类图如下所示:

代码语言:javascript
复制
  +-------------+        +----------------+
  |   Subject   | -----> |   Observer     |
  +-------------+        +----------------+
  | + attach(o) |        | + update()     |
  | + detach(o) |        +----------------+
  | + notify()  |
  +-------------+

假设我们有一个简单的气象站应用,气象站会定期测量温度、湿度和气压。我们希望当气象数据发生变化时,能够实时地通知给注册的观察者。

  • 让我们通过一个简单的气象站应用来演示观察者模式的实现。
  • WeatherStation.java
代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;

// 主题接口
interface Subject {
    // 注册观察者
    void registerObserver(Observer observer);
    // 移除观察者
    void removeObserver(Observer observer);
    // 通知所有观察者
    void notifyObservers();
}

// 观察者接口
interface Observer {
    // 更新观察者状态
    void update(float temperature, float humidity, float pressure);
}

// 具体主题类
class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    // 构造函数
    public WeatherData() {
        observers = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer observer) {
        // 添加观察者到列表
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        // 从列表中移除观察者
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        // 通知所有观察者
        for (Observer observer : observers) {
            observer.update(temperature, humidity, pressure);
        }
    }

    // 当气象数据发生变化时调用该方法
    public void measurementsChanged() {
        notifyObservers();
    }

    // 设置气象数据
    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        // 数据变化后通知观察者
        measurementsChanged();
    }
}

// 具体观察者类
class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;

    @Override
    public void update(float temperature, float humidity, float pressure) {
        // 更新观察者状态
        this.temperature = temperature;
        this.humidity = humidity;
        // 显示当前气象数据
        display();
    }

    // 显示当前气象数据
    public void display() {
        System.out.println("Current conditions: " + temperature
                + "F degrees and " + humidity + "% humidity");
    }
}

public class WeatherStation {
    public static void main(String[] args) {
        // 创建主题对象
        WeatherData weatherData = new WeatherData();

        // 创建观察者对象
        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();

        // 注册观察者到主题对象
        weatherData.registerObserver(currentDisplay);

        // 模拟气象数据变化
        weatherData.setMeasurements(80, 65, 30.4f);
        weatherData.setMeasurements(82, 70, 29.2f);
        weatherData.setMeasurements(78, 90, 29.2f);
    }
}

这段代码实现了一个简单的气象站应用。WeatherData 类是主题,它维护了观察者列表,并提供了方法来注册、移除和通知观察者。CurrentConditionsDisplay 类是具体的观察者,它实现了 Observer 接口,并在更新时显示当前的气象数据。

main 方法中,我们创建了一个 WeatherData 对象和一个 CurrentConditionsDisplay 对象,并将后者注册为前者的观察者。然后,我们模拟了几次气象数据的变化,并观察观察者的更新情况。

  • 运行结果 以下是代码的运行结果:
代码语言:javascript
复制
Current conditions: 80.0F degrees and 65.0% humidity
Current conditions: 82.0F degrees and 70.0% humidity
Current conditions: 78.0F degrees and 90.0% humidity

这个结果显示了每次调用 setMeasurements() 方法后,CurrentConditionsDisplay 观察者都会接收到通知,并且显示当前的气象条件(温度和湿度)。

main 方法中,创建了一个 WeatherData 对象和一个 CurrentConditionsDisplay 对象,并将后者注册为前者的观察者。然后,模拟了几次气象数据的变化,并观察观察者的更新情况。

观察者模式的应用场景
1. GUI 开发

在图形用户界面(GUI)开发中,观察者模式被广泛应用。例如,按钮、复选框、滚动条等 GUI 组件可以作为主题,而窗口、文本框等可以作为观察者。当用户与 GUI 组件进行交互时,观察者会接收到通知并执行相应的操作,从而实现 GUI 的实时更新和交互。

2. 股票市场监控系统

股票市场监控系统需要实时监测股票价格的变化,并及时通知相关的投资者或交易员。股票价格变化可以作为主题,而投资者或交易员可以作为观察者。当股票价格发生变化时,观察者会收到通知并做出相应的交易决策。

3. 车辆追踪系统

在车辆追踪系统中,车辆的位置和状态需要实时监测,并及时通知相关的监控中心或用户。车辆的位置和状态可以作为主题,而监控中心或用户可以作为观察者。当车辆的位置或状态发生变化时,观察者会收到通知并进行相应的处理。

4. 观察者模式与事件驱动编程

观察者模式与事件驱动编程密切相关。在事件驱动编程中,事件是主题,而事件处理程序则是观察者。当事件发生时,观察者会收到通知并执行相应的处理逻辑,从而实现程序的事件驱动和响应机制。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 深入理解观察者模式(Observer Pattern)
    • 为什么使用观察者模式?
    • 核心概念
    • 观察者模式的结构
    • 观察者模式的应用场景
      • 1. GUI 开发
      • 2. 股票市场监控系统
      • 3. 车辆追踪系统
      • 4. 观察者模式与事件驱动编程
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档