Java观察者模式
观察者模式是一种设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象。当主题对象的状态发生变化时,它会自动通知所有的观察者对象,使它们能够更新自己。
概述
在软件开发中,经常会遇到需要通知多个对象的情况。例如,当一个对象的状态发生改变时,我们需要通知其他对象进行相应的处理。传统的方式是在主题对象中维护一个观察者列表,当状态发生改变时,遍历观察者列表并调用它们的更新方法。这种方式存在的问题是主题对象和观察者对象之间的耦合度较高,当观察者对象的数量增加或减少时,需要修改主题对象的代码。
观察者模式通过引入抽象的观察者和主题接口,解耦了主题对象和观察者对象之间的依赖关系,使它们可以独立地演化。当主题对象的状态发生改变时,主题对象会通知所有的观察者对象,观察者对象根据需要自行更新。
模式结构
观察者模式由四个核心角色组成:
- Subject(主题):主题是被观察的对象,它维护观察者列表,并提供注册和取消注册观察者的方法,以及通知观察者的方法。
- ConcreteSubject(具体主题):具体主题是主题的具体实现类,它负责维护对象的状态,并在状态发生改变时通知观察者。
- Observer(观察者):观察者是接收到主题通知的对象,它定义了一个更新方法,用于接收主题通知后的操作。
- ConcreteObserver(具体观察者):具体观察者是观察者的具体实现类,它实现了更新方法,并在接收到主题通知后执行相应的操作。
![观察者模式流程图](
代码示例
下面的例子演示了一个简单的观察者模式的实现。假设有一个主题对象WeatherData
,它负责维护天气数据,并在数据发生变化时通知观察者。
首先,我们定义一个主题接口Subject
和观察者接口Observer
:
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
public interface Observer {
void update();
}
然后,我们实现具体的主题类WeatherData
和观察者类CurrentConditionsDisplay
:
import java.util.ArrayList;
import java.util.List;
public class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<>();
}
public void registerObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
notifyObservers();
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
}
public class CurrentConditionsDisplay implements Observer {
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update() {
float temperature = weatherData.getTemperature();
float humidity = weatherData.getHumidity();
System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
}
}
在主函数中,我们创建一个WeatherData
对象和一个CurrentConditionsDisplay
对象,并模拟数据