观察者模式 (Observer)
一个对象状态变化,其他依赖它的对象都要做出反应?观察者模式为你提供了完美的解决方案,当一个对象变化时,所有依赖它的对象都会收到通知并自动更新。
在实际开发中,很多时候我们希望某个对象的状态变化能即时通知到其他对象,而不用每次都手动更新所有依赖的对象。观察者模式就像是一个通知系统,当某个对象的状态发生变化时,所有订阅了这个对象的“观察者”都会第一时间接到通知,并进行相应的操作。就像是股票市场的行情变化,一旦某只股票的价格波动,所有的投资者(观察者)都会立即得到通知,从而做出决策。
趣味解读:生活中的“天气预报”
想象一下,你每天早晨都通过手机查看天气预报,得知今天是否下雨。这里,天气变化是“被观察者”,而你就是“观察者”。当天气发生变化时,天气预报系统(被观察者)会及时通知你(观察者),你可以根据天气情况决定是否带伞、穿外套等。这就是观察者模式的运作原理:天气变化(被观察者)通知你(观察者)进行相应的反应。
Java代码案例:观察者模式 - 简单的气象站
假设你正在开发一个气象站系统,气象站实时监测温度,并将温度变化通知给所有注册的观察者(比如显示屏、打印机、移动应用等)。通过观察者模式,你可以在不直接依赖每个显示设备的情况下,轻松实现温度变化通知。
// 1. 观察者接口
interface Observer {
void update(float temperature);
}
// 2. 被观察者接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 3. 具体的被观察者 - 气象站
class WeatherStation implements Subject {
private float temperature;
private List<Observer> observers = new ArrayList<>();
public void setTemperature(float temperature) {
this.temperature = temperature;
notifyObservers(); // 温度变化时通知所有观察者
}
@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); // 将当前温度传递给所有观察者
}
}
}
// 4. 具体观察者 - 显示屏
class DisplayScreen implements Observer {
@Override
public void update(float temperature) {
System.out.println("Display Screen: Current Temperature is " + temperature + "°C");
}
}
// 5. 具体观察者 - 打印机
class Printer implements Observer {
@Override
public void update(float temperature) {
System.out.println("Printer: Printing current temperature: " + temperature + "°C");
}
}
// 6. 客户端代码
public class Main {
public static void main(String[] args) {
// 创建气象站
WeatherStation weatherStation = new WeatherStation();
// 创建并注册观察者
DisplayScreen displayScreen = new DisplayScreen();
Printer printer = new Printer();
weatherStation.registerObserver(displayScreen);
weatherStation.registerObserver(printer);
// 设置温度,所有观察者会收到通知
weatherStation.setTemperature(25.5f);
weatherStation.setTemperature(30.2f);
}
}
解析:
观察者接口:
Observer
接口定义了一个update()
方法,用于接收并处理状态变化的通知。被观察者接口:
Subject
接口定义了管理观察者的方法,包括注册、删除和通知观察者。具体的被观察者 - 气象站:
WeatherStation
类实现了Subject
接口,当温度变化时,气象站会通知所有已注册的观察者。具体观察者 - 显示屏和打印机:
DisplayScreen
和Printer
类分别实现了Observer
接口,并在收到温度变化通知时进行更新操作。客户端代码:在
Main
类中,我们创建了气象站对象和两个观察者对象(显示屏和打印机),并注册了这些观察者。当气象站的温度发生变化时,所有观察者都会接收到更新的通知。
运行结果:
Display Screen: Current Temperature is 25.5°C
Printer: Printing current temperature: 25.5°C
Display Screen: Current Temperature is 30.2°C
Printer: Printing current temperature: 30.2°C
实际应用场景:
UI界面更新:观察者模式常用于GUI应用中。当一个模型对象的状态变化时,所有需要显示这些数据的界面(如表格、图表等)都会自动更新,用户界面不需要直接知道这些数据的具体变化。
事件驱动编程:在一些事件驱动的编程模型中,比如Web开发或前端开发,用户的操作会触发事件,观察者模式可以帮助管理这些事件的响应,确保系统的模块化和解耦。
社交网络通知系统:例如,社交网络中,当一个用户发布了新动态,所有关注该用户的其他用户都会收到通知。这里,发布者是被观察者,所有关注者是观察者。
总结
观察者模式通过建立一个“观察者”与“被观察者”之间的关系,让多个对象能够在某个对象状态发生变化时及时响应。它的优势在于减少了对象之间的耦合性,提高了系统的灵活性和可扩展性。在很多需要动态更新界面或通知其他对象的场景中,观察者模式都是一个非常有效的设计模式。