目录
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件处理机制、模型-视图架构(MVC)中的视图更新、以及异步消息处理等场景。
观察者模式的关键组成部分
- 主题(Subject):也称为被观察者。它可以有多个观察者,当它的状态发生变化时,会通知所有的观察者。
- 观察者(Observer):观察者对象实现了一个更新方法,当收到主题的通知时,就会执行此方法进行相应的更新操作。
- 事件(Event):通常是主题状态的变化或其他重要事件的发生。
观察者模式的实现步骤
- 定义观察者的接口:通常包含一个更新方法。
- 定义主题的接口:通常包含添加、移除观察者的方法以及通知观察者的方法。
- 实现具体的观察者:实现观察者接口,定义更新逻辑。
- 实现具体的主题:实现主题接口,管理观察者列表并在状态变化时通知观察者。
观察者模式的示例
假设我们要实现一个天气预报系统,其中有一个天气数据源(作为主题)和多个显示设备(作为观察者),当天气数据发生变化时,显示设备需要更新自己的显示内容。
步骤1:定义观察者接口
java
深色版本
1public interface Observer {
2 void update(float temp, float humidity, float pressure);
3}
步骤2:定义主题接口
java
深色版本
1import java.util.ArrayList;
2import java.util.List;
3
4public interface Subject {
5 void registerObserver(Observer o);
6 void removeObserver(Observer o);
7 void notifyObservers(float temp, float humidity, float pressure);
8}
步骤3:实现具体观察者
java
深色版本
1public class CurrentConditionsDisplay implements Observer {
2 private float temperature;
3 private float humidity;
4
5 @Override
6 public void update(float temp, float humidity, float pressure) {
7 this.temperature = temp;
8 this.humidity = humidity;
9 display();
10 }
11
12 private void display() {
13 System.out.println("Current conditions: " + temperature + " F degrees and " + humidity + "% humidity");
14 }
15}
步骤4:实现具体主题
java
深色版本
1public class WeatherData implements Subject {
2 private List<Observer> observers;
3 private float temperature;
4 private float humidity;
5 private float pressure;
6
7 public WeatherData() {
8 observers = new ArrayList<>();
9 }
10
11 @Override
12 public void registerObserver(Observer o) {
13 observers.add(o);
14 }
15
16 @Override
17 public void removeObserver(Observer o) {
18 int i = observers.indexOf(o);
19 if (i >= 0) {
20 observers.remove(i);
21 }
22 }
23
24 @Override
25 public void notifyObservers(float temp, float humidity, float pressure) {
26 for (Observer observer : observers) {
27 observer.update(temp, humidity, pressure);
28 }
29 }
30
31 public void setMeasurements(float temp, float humidity, float pressure) {
32 this.temperature = temp;
33 this.humidity = humidity;
34 this.pressure = pressure;
35 measurementsChanged();
36 }
37
38 private void measurementsChanged() {
39 notifyObservers(temperature, humidity, pressure);
40 }
41}
步骤5:客户端代码
java
深色版本
1public class WeatherStation {
2 public static void main(String[] args) {
3 WeatherData weatherData = new WeatherData();
4 CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();
5
6 weatherData.registerObserver(currentDisplay);
7
8 // 模拟天气数据变化
9 weatherData.setMeasurements(80, 65, 30.4f);
10 weatherData.setMeasurements(82, 70, 29.2f);
11 weatherData.setMeasurements(78, 90, 29.2f);
12 }
13}
运行结果
当你运行 WeatherStation
类时,你会看到输出如下:
深色版本
1Current conditions: 80.0 F degrees and 65.0 % humidity
2Current conditions: 82.0 F degrees and 70.0 % humidity
3Current conditions: 78.0 F degrees and 90.0 % humidity
观察者模式的优点
- 解耦:观察者模式降低了对象之间的耦合度,主题和观察者之间没有直接的引用关系。
- 扩展性:可以方便地添加新的观察者,而无需修改主题或现有观察者的代码。
- 灵活性:观察者可以根据自身需要做出响应,提高了系统的灵活性。
观察者模式的缺点
- 性能问题:如果观察者数量较多,同时通知所有观察者可能会导致性能下降。
- 循环依赖:如果不小心处理,可能会导致主题和观察者之间的循环依赖。
总结来说,观察者模式是一种非常实用的设计模式,尤其是在需要实现事件驱动的系统或需要动态维护对象之间的依赖关系时。