本文目录导读:

我来通过一个具体的Java案例来演示观察者模式的实现,观察者模式定义了对象之间的一对多依赖关系,当一个对象状态发生变化时,所有依赖它的对象都会得到通知并自动更新。
案例:天气预报系统
我们将实现一个天气预报系统,当天气数据更新时,多个显示设备会自动更新显示。
定义观察者接口和目标接口
import java.util.ArrayList;
import java.util.List;
// 观察者接口
interface Observer {
void update(float temperature, float humidity, float pressure);
}
// 主题接口(被观察者)
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
实现具体的目标类(天气数据)
// 天气数据类(具体被观察者)
class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer o) {
if (!observers.contains(o)) {
observers.add(o);
System.out.println("注册了一个观察者");
}
}
@Override
public void removeObserver(Observer o) {
if (observers.contains(o)) {
observers.remove(o);
System.out.println("移除了一个观察者");
}
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
// 当天气数据更新时调用
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public void measurementsChanged() {
notifyObservers();
}
}
实现具体的观察者(显示设备)
// 当前状况显示
class CurrentConditionsDisplay implements Observer {
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
public void display() {
System.out.println("当前情况: " + temperature + "°C, 湿度: " + humidity + "%");
}
}
// 统计显示
class StatisticsDisplay implements Observer {
private float maxTemp = Float.MIN_VALUE;
private float minTemp = Float.MAX_VALUE;
private float tempSum = 0.0f;
private int numReadings;
private Subject weatherData;
public StatisticsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temperature, float humidity, float pressure) {
tempSum += temperature;
numReadings++;
if (temperature > maxTemp) {
maxTemp = temperature;
}
if (temperature < minTemp) {
minTemp = temperature;
}
display();
}
public void display() {
System.out.println("温度统计: 平均 " + (tempSum / numReadings)
+ ", 最高 " + maxTemp + ", 最低 " + minTemp);
}
}
// 天气预报显示
class ForecastDisplay implements Observer {
private float currentPressure = 29.92f;
private float lastPressure;
private Subject weatherData;
public ForecastDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temperature, float humidity, float pressure) {
lastPressure = currentPressure;
currentPressure = pressure;
display();
}
public void display() {
System.out.print("天气预报: ");
if (currentPressure > lastPressure) {
System.out.println("天气正在改善");
} else if (currentPressure == lastPressure) {
System.out.println("天气保持不变");
} else {
System.out.println("天气可能变糟");
}
}
}
测试类
public class WeatherStation {
public static void main(String[] args) {
// 创建天气数据对象(被观察者)
WeatherData weatherData = new WeatherData();
// 创建观察者(显示设备)
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
System.out.println("=== 第一次天气更新 ===");
weatherData.setMeasurements(25.0f, 65.0f, 1013.0f);
System.out.println("\n=== 第二次天气更新 ===");
weatherData.setMeasurements(28.0f, 70.0f, 1015.0f);
// 移除一个观察者
System.out.println("\n=== 移除一个观察者后 ===");
weatherData.removeObserver(statisticsDisplay);
weatherData.setMeasurements(22.0f, 55.0f, 1008.0f);
}
}
运行结果
注册了一个观察者
注册了一个观察者
注册了一个观察者
=== 第一次天气更新 ===
当前情况: 25.0°C, 湿度: 65.0%
温度统计: 平均 25.0, 最高 25.0, 最低 25.0
天气预报: 天气保持不变
=== 第二次天气更新 ===
当前情况: 28.0°C, 湿度: 70.0%
温度统计: 平均 26.5, 最高 28.0, 最低 25.0
天气预报: 天气正在改善
=== 移除一个观察者后 ===
移除了一个观察者
当前情况: 22.0°C, 湿度: 55.0%
天气预报: 天气可能变糟
观察者模式的关键点
-
松耦合:主题(Subject)和观察者(Observer)之间是松耦合的,主题只知道观察者实现了Observer接口,不需要知道观察者的具体实现。
-
一对多关系:一个主题可以有多个观察者,当主题状态变化时,所有注册的观察者都会收到通知。
-
支持广播通信:主题通过
notifyObservers()方法向所有观察者广播状态变化。 -
观察者可以随时注册或注销:观察者可以在运行时动态地添加或移除。
使用Java内置的观察者模式
Java也提供了内置的观察者模式支持(java.util.Observable和java.util.Observer),但需要注意这种方式有一些限制(Observable是类而不是接口,没有实现Serializable等),实际开发中推荐使用自定义的观察者模式实现,更加灵活。
这个案例展示了观察者模式在实际开发中的应用,可以根据具体需求进行扩展和修改。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播