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

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

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


简介:

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


为什么使用观察者模式?


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


核心概念


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


观察者模式的结构


  • Subject(主题):

注册和移除观察者的方法

通知观察者的方法


  • Observer(观察者):

更新方法,用于接收主题状态的变化


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

  +-------------+        +----------------+
  |   Subject   | -----> |   Observer     |
  +-------------+        +----------------+
  | + attach(o) |        | + update()     |
  | + detach(o) |        +----------------+
  | + notify()  |
  +-------------+

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


  • 让我们通过一个简单的气象站应用来演示观察者模式的实现。
  • WeatherStation.java
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 对象,并将后者注册为前者的观察者。然后,我们模拟了几次气象数据的变化,并观察观察者的更新情况。


  • 运行结果

以下是代码的运行结果:

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. 观察者模式与事件驱动编程

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


相关文章
|
6月前
|
设计模式 Java
Java设计模式:什么是观察者模式(Observer Pattern)?
Java设计模式:什么是观察者模式(Observer Pattern)?
62 0
|
设计模式
设计模式16 - 观察者模式【Observer Pattern】
设计模式16 - 观察者模式【Observer Pattern】
48 0
|
设计模式 Java uml
观察者模式(Observer Pattern)
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象间的一种一对多的依赖关系,使得一个对象的状态发生改变时,所有依赖于它的对象都能够得到通知并自动更新。
84 1
|
存储 设计模式 前端开发
详解Java设计模式之观察者模式(Observer Pattern)
详解Java设计模式之观察者模式(Observer Pattern)
168 0
详解Java设计模式之观察者模式(Observer Pattern)
|
Java 程序员
行为型模式 - 观察者模式(Observer Pattern)
行为型模式 - 观察者模式(Observer Pattern)
|
设计模式 JavaScript 调度
JS案例:Observer Pattern(观察者模式)和Publisher-Subscriber Pattern(发布者/订阅者模式)
JS案例:Observer Pattern(观察者模式)和Publisher-Subscriber Pattern(发布者/订阅者模式)
134 0
JS案例:Observer Pattern(观察者模式)和Publisher-Subscriber Pattern(发布者/订阅者模式)
|
设计模式 Java
设计模式九: 观察者模式(Observer Pattern)
简介 观察者属于行为型模式的一种, 又叫发布-订阅模式. 如果一个对象的状态发生改变,依赖他的对象都将发生变化, 那么这种情况就适合使用观察者模式. 它包含两个术语,主题(Subject),观察者(Observer), 主题管理一个观察者的列表, 并在状态发生变化时通知到他们.
1047 0
观察者模式(Observer )
对象间的联动——观察者模式(一)对象间的联动——观察者模式(二)对象间的联动——观察者模式(三)对象间的联动——观察者模式(四)对象间的联动——观察者模式(五)对象间的联动——观察者模式(五)
761 0
|
C#
C#设计模式之十六观察者模式(Observer Pattern)【行为型】
原文:C#设计模式之十六观察者模式(Observer Pattern)【行为型】 一、引言   今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份)把所有的模式写完,2018年,新的一年写一些新的东西。
1414 0