十一、观察者模式(行为型)
观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象发生改变时,所有依赖于它的对象都会自动接收通知并进行更新。
观察者模式通常由两部分组成:主题(Subject)和观察者(Observer)。主题维护着一个观察者列表,并且在状态发生改变时通知这些观察者。观察者则订阅主题的状态,并在状态发生改变时接收通知并进行相应的操作。
观察者模式被广泛地应用于事件驱动系统中,例如用户界面、网络通信和消息队列等领域。通过使用观察者模式,我们可以解耦主题与观察者之间的关系,从而实现更加灵活的设计。
总之,观察者模式提供了一种简单、灵活的方法来处理多个对象之间的一对多依赖关系。它有助于降低系统的耦合度,并且允许我们实现更加灵活的设计。
示例代码
对象间的一对多的依赖关系。
package cn.leetcode;
interface Observer {
void update(float temperature, float humidity, float pressure);
}
package cn.leetcode;
interface Subject {
// 注册观察者
void registerObserver(Observer observer);
// 移除观察者
void removeObserver(Observer observer);
// 通知所有观察者
void notifyObservers();
}
package cn.leetcode;
import java.util.ArrayList;
import java.util.List;
// 具体的被观察对象类
class WeatherData implements Subject {
// 观察者列表
private List<Observer> observers = new ArrayList<>();
// 温度
private float temperature;
// 湿度
private float humidity;
// 气压
private float pressure;
// 设置测量数据,并通知观察者
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged(); // 数据已改变,通知观察者
}
// 数据已改变,通知观察者
public void measurementsChanged() {
// 通知所有观察者
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, humidity, pressure);
}
}
}
package cn.leetcode;
// 具体的观察者类,用于显示当前天气状况
class CurrentConditionsDisplay implements Observer {
// 温度
private float temperature;
// 湿度
private float humidity;
// 气压
private float pressure;
// 被观察对象
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;
this.pressure = pressure;
// 显示当前天气状况
display();
}
// 显示当前天气状况
public void display() {
System.out.println("当前的天气: 华氏度 " + temperature + ",湿度 " + humidity + "%,气压 " + pressure + "。");
}
}
package cn.leetcode;
public class Client {
public static void main(String[] args) {
// 创建被观察对象
WeatherData weatherData = new WeatherData();
// 创建观察者
new CurrentConditionsDisplay(weatherData);
// 更新数据并通知观察者
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 70, 29.2f);
weatherData.setMeasurements(78, 90, 29.2f);
}
}
输出:
当前的天气: 华氏度 80.0,湿度 65.0%,气压 30.4。
当前的天气: 华氏度 82.0,湿度 70.0%,气压 29.2。
当前的天气: 华氏度 78.0,湿度 90.0%,气压 29.2。
使用 JDK 提供的类实现观察者模式
在 JDK 中,观察者模式已经被封装成了一个工具类 java.util.Observable 和一个接口 java.util.Observer。下面是一个简单的示例代码,演示如何使用这两个类来实现观察者模式:
package cn.leetcode.jdk;
import java.util.Observable;
// 主题类,继承自 Observable
public class Subject extends Observable {
private int data;
public void setData(int data) {
this.data = data;
setChanged();
notifyObservers();
}
public int getData() {
return data;
}
}
package cn.leetcode.jdk;
import java.util.Observable;
import java.util.Observer;
// 观察者类,实现 Observer 接口
public class ObserverA implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("观察者 A 收到数据: " + ((Subject) o).getData());
}
}
package cn.leetcode.jdk;
import java.util.Observable;
import java.util.Observer;
public class ObserverB implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("观察者 B 收到数据: " + ((Subject) o).getData());
}
}
package cn.leetcode.jdk;
public class Client {
public static void main(String[] args) {
Subject subject = new Subject();
ObserverA observerA = new ObserverA();
ObserverB observerB = new ObserverB();
// 注册观察者
subject.addObserver(observerA);
subject.addObserver(observerB);
// 修改主题数据并通知观察者
subject.setData(10);
subject.setData(20);
}
}
输出:
观察者 B 收到数据: 10
观察者 A 收到数据: 10
观察者 B 收到数据: 20
观察者 A 收到数据: 20
在这个示例中,我们创建了一个主题类 Subject,它继承自 Observable 并包含一些数据。当主题数据发生变化时,我们调用 setChanged() 方法标记数据已经改变,并调用 notifyObservers() 方法通知所有观察者。
同时,我们定义了两个观察者类 ObserverA 和 ObserverB,它们实现了 Observer 接口,其中的 update() 方法会在主题数据发生变化时被调用。
在 Client 类中,我们创建了一个 Subject 对象和两个观察者对象,并通过 addObserver() 方法将观察者注册到主题中。随后,我们修改了主题数据并通知了所有观察者,观察者收到通知后输出相应的信息。
总结
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象能够同时监听某一个主题对象,当主题对象发生变化时会自动通知所有观察者对象,使得它们能够及时更新自己的状态。观察者模式的核心是主题和观察者之间的解耦,让它们能够独立地变化和扩展,从而提高了系统的灵活性和可维护性。在观察者模式中,主题通常是一个抽象类或接口,而观察者通常是具体的实现类,它们之间通过注册和通知的方式进行交互。
阅读量:2015
点赞量:0
收藏量:0