Java 编程之观察者模式详解

一、什么是观察者模式?

观察者模式(Observer Pattern)是一种行为型设计模式,用于对象之间的一对多依赖关系:当被观察对象(Subject)状态发生变化时,所有依赖它的观察者(Observer)都会自动收到通知并更新

拿天气预报系统来类比
假设你是一个气象局的中央发布系统,每当你更新天气预报,订阅了你天气服务的各种渠道(如手机 App、LED 公交站牌、广播系统)都会自动收到通知并显示新的天气情况。

  • 气象局 = 被观察者(Subject)
  • 各种显示设备 = 观察者(Observer)
  • 通知机制 = 观察者模式的核心精髓

二、模式结构图

在这里插入图片描述

三、代码实战

我们构建一个完整的天气通知系统:

  • WeatherStation 是被观察者
  • PhoneDisplayLedBoardDisplay 是观察者

1. Observer 接口

public interface Observer {
    void update(float temperature, float humidity, float pressure);
}

2. Subject 接口

public interface Subject {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();
}

3. WeatherStation(被观察者)

import java.util.ArrayList;
import java.util.List;

public class WeatherStation implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private float temperature, humidity, pressure;

    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        observers.remove(o);
    }

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

    public void setMeasurements(float temp, float hum, float press) {
        this.temperature = temp;
        this.humidity = hum;
        this.pressure = press;
        notifyObservers(); // 状态变了,通知大家!
    }
}

4. 两个观察者实现类

手机显示端

public class PhoneDisplay implements Observer {
    @Override
    public void update(float temperature, float humidity, float pressure) {
        System.out.println("[手机App] 当前天气:温度=" + temperature + "℃,湿度=" + humidity + "%,气压=" + pressure + " hPa");
    }
}

LED 公交站牌

public class LedBoardDisplay implements Observer {
    @Override
    public void update(float temperature, float humidity, float pressure) {
        System.out.println("[LED站牌] 实时天气:T=" + temperature + "℃ | H=" + humidity + "% | P=" + pressure + " hPa");
    }
}

5. 主程序测试

public class WeatherApp {
    public static void main(String[] args) {
        WeatherStation station = new WeatherStation();

        Observer phone = new PhoneDisplay();
        Observer led = new LedBoardDisplay();

        station.registerObserver(phone);
        station.registerObserver(led);

        station.setMeasurements(28.5f, 60f, 1012f);
        station.setMeasurements(30.1f, 55f, 1008f);
    }
}

四、实战示例UML 图

@startuml
interface Observer {
    +update(temp, humidity, pressure)
}

interface Subject {
    +registerObserver(o: Observer)
    +removeObserver(o: Observer)
    +notifyObservers()
}

class WeatherStation implements Subject {
    -observers: List<Observer>
    -temperature: float
    -humidity: float
    -pressure: float
    +setMeasurements(temp, hum, press)
}

class PhoneDisplay implements Observer
class LedBoardDisplay implements Observer

Subject <|.. WeatherStation
Observer <|.. PhoneDisplay
Observer <|.. LedBoardDisplay
WeatherStation --> Observer : notifies >>
@enduml

五、优点与应用场景

优点

  • 低耦合性:Subject 和 Observer 相互独立,只通过接口联系;
  • 灵活可扩展:任意添加/删除观察者,不影响其他模块;
  • 符合开闭原则:修改 Subject 不影响 Observer 行为。

典型应用场景

  • GUI 事件系统(按钮点击监听)
  • 消息订阅与发布(如 Kafka、MQTT)
  • 数据驱动的响应式 UI 框架(React/Vue 背后的思想)
  • 游戏状态监听器(如玩家血量变化通知 UI)

六、小结

一句话总结观察者模式: “我变了,我的订阅者们会立刻知道。”

观察者模式本质上是发布-订阅模式的一种实现。通过本篇“天气预报”类比,我们不仅理解了模式的结构,还体验了它在实际开发中的强大威力。

七、参考

《23种设计模式概览》
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勤奋的知更鸟

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值