一、什么是观察者模式
观察者模式(Observer Pattern )是一种行为型的设计模式,它定义了一种一对多的依赖关系,当一个对象(被观察者)的状态发生变化时,依赖它的所有对象(观察者)可以感知到这种状态的变化。
核心角色和结构
**主题(Subject):**被观察者 这是一个抽象类或者接口 。负责维护观察者列表,提供注册、销毁、通知的方法。
**具体主题(ConcreteSubject):**具体的被观察者、储存具体的状态,当状态发生变化时,通知所有的观察者。
观察者(Observer): 接收主题通知的对象、提供一个更新方法、收到通知时主题会调用该方法更新状态
**具体观察者(Concrete Observer):**实现Observer接口,状态更新时执行具体的逻辑操作。
使用场景
当一个对象的状态变化时需要同步更新到其他对象时。
二、JAVA案例
使用观察者模式模拟天气预报站示例
主题接口
java
/**
* 主题接口
* <p>
* 这是观察者模式中的主题(Subject)角色,也称为被观察者或可观察者。
* 该接口定义了管理观察者的基本操作,包括注册、移除和通知观察者。
* 实现此接口的类负责维护观察者列表,并在状态变化时通知所有注册的观察者。
*
* @author LiuBi
* @version 1.0
* @createDate 2026/4/18 22:30
**/
public interface Subject {
/**
* 注册观察者
* <p>
* 将指定的观察者添加到观察者列表中,使其能够接收主题的状态变化通知。
*
* @param observer 要注册的观察者对象
*/
void registerObserver(Observer observer);
/**
* 移除观察者
* <p>
* 从观察者列表中移除指定的观察者,使其不再接收主题的状态变化通知。
*
* @param observer 要移除的观察者对象
*/
void removeObserver(Observer observer);
/**
* 通知所有观察者
* <p>
* 遍历观察者列表,调用每个观察者的update方法,将它们通知到主题的最新状态变化。
*/
void notifyObservers();
}
观察者模式中的具体主题
java
import java.util.ArrayList;
import java.util.List;
/**
* 天气数据类
* <p>
* 这是观察者模式中的具体主题(Concrete Subject)角色,代表具体的天气数据源。
* 该类继承自Subject接口,负责维护天气数据(如温度、湿度、气压等),
* 并在天气数据发生变化时通知所有已注册的观察者。
*
* @author LiuBi
* @version 1.0
* @createDate 2026/4/18 22:33
**/
public class WeatherDate implements Subject {
private float temperature;
private final List<Observer> observers;
public WeatherDate() {
observers = new ArrayList<>();
}
/**
* 设置温度并通知观察者
* <p>
* 更新当前温度值,并自动通知所有已注册的观察者关于温度变化的信息。
*
* @param temperature 要设置的温度值
*/
public void setTemperature(float temperature) {
this.temperature = temperature;
notifyObservers();
}
/**
* 注册观察者
* <p>
* 将指定的观察者添加到观察者列表中,使其能够接收主题的状态变化通知。
*
* @param observer 要注册的观察者对象
*/
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
/**
* 移除观察者
* <p>
* 从观察者列表中移除指定的观察者,使其不再接收主题的状态变化通知。
*
* @param observer 要移除的观察者对象
*/
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
/**
* 通知所有观察者
* <p>
* 遍历观察者列表,调用每个观察者的update方法,将它们通知到主题的最新状态变化。
*/
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature);
}
}
}
观察者接口
java
/**
* 观察者接口
* <p>
* 这是观察者模式中的观察者角色,用于定义观察者的行为规范。
* 实现此接口的类可以订阅主题(Subject)的状态变化通知,
* 并在主题状态改变时接收更新信息并执行相应的处理逻辑。
*
* @author LiuBi
* @version 1.0
* @createDate 2026/4/18 22:24
**/
public interface Observer {
/**
* 更新观察者的状态
* <p>
* 当主题(Subject)的状态发生变化时调用此方法,通知观察者最新的温度数据。
* 实现此接口的类需要根据新的温度值执行相应的业务逻辑或界面更新。
*
* @param temperature 最新的温度值
*/
void update(float temperature);
}
观察者模式中的具体观察者
java
/**
* 手机显示屏类
* <p>
* 这是观察者模式中的具体观察者(Concrete Observer)角色,代表手机端的天气显示界面。
* 该类实现Observer接口,当天气数据发生变化时接收温度更新通知,
* 并在手机显示屏上展示最新的温度信息。
*
* @author LiuBi
* @version 1.0
* @createDate 2026/4/18 22:35
**/
public class PhoneDisplay implements Observer {
/**
* 更新观察者的状态
* <p>
* 当主题(Subject)的状态发生变化时调用此方法,通知观察者最新的温度数据。
* 实现此接口的类需要根据新的温度值执行相应的业务逻辑或界面更新。
*
* @param temperature 最新的温度值
*/
@Override
public void update(float temperature) {
System.out.println("📱 手机显示屏收到更新:当前温度 " + temperature + "°C");
}
}
测试
java
public class Test {
public static void main(String[] args) {
WeatherDate weatherDate = new WeatherDate();
Observer observer = new PhoneDisplay();
Observer observer1 = new PhoneDisplay();
weatherDate.registerObserver(observer);
weatherDate.registerObserver(observer1);
weatherDate.setTemperature(25.0f);
weatherDate.setTemperature(30.0f);
}
}
测试结果

三、总结
观察者模式符合开闭原则、新增观察者时只需实现接口注册即可,无需修改主题代码。当观察者数量变得庞大起来时,可能能导致程序卡顿。