观察者模式属于行为型设计模式,用于建立对象间的一对多依赖关系。当主题(Subject)状态变化时,所有依赖的观察者(Observer)会自动收到通知并更新。
// 1. 主题接口
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
// 2. 观察者接口
interface Observer {
void update(float temp, float humidity, float pressure);
}
// 3. 具体主题实现
class WeatherData implements Subject {
private List<Observer> observers = new ArrayList<>();
private float temperature;
private float humidity;
private float pressure;
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer o : observers) {
o.update(temperature, humidity, pressure);
}
}
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
// 4. 具体观察者实现
class CurrentConditionsDisplay implements Observer {
private float temperature;
private float humidity;
public CurrentConditionsDisplay(Subject weatherData) {
weatherData.registerObserver(this);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
display();
}
public void display() {
System.out.println("Current conditions: " + temperature
+ "°C and " + humidity + "% humidity");
}
}
// 5. 使用示例
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay display = new CurrentConditionsDisplay(weatherData);
weatherData.setMeasurements(25.5f, 65, 1013.1f);
weatherData.setMeasurements(26.8f, 70, 1012.5f);
}
}
特性 | 推模型(Push) | 拉模型(Pull) |
---|---|---|
数据传递方式 | 主题主动发送完整数据 | 观察者从主题拉取所需数据 |
实现复杂度 | 观察者可能收到不需要的数据 | 观察者按需获取数据,需要维护主题引用 |
耦合度 | 观察者依赖具体数据结构 | 观察者只需知道主题存在 |
性能考量 | 可能传输冗余数据 | 需要多次调用获取方法 |
拉模型改进示例:
interface Subject {
// 新增获取状态的方法
float getTemperature();
float getHumidity();
float getPressure();
}
class WeatherData implements Subject {
// 保持原有接口不变
// 新增状态获取方法...
}
class CurrentConditionsDisplay implements Observer {
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update() {
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
display();
}
}
// 已过时,不推荐使用,仅作了解
import java.util.Observable;
import java.util.Observer;
class WeatherData extends Observable {
public void measurementsChanged() {
setChanged(); // 必须调用
notifyObservers(); // 无参为拉模型
// notifyObservers(data); // 带参为推模型
}
}
class Display implements Observer {
@Override
public void update(Observable o, Object arg) {
if (o instanceof WeatherData) {
// 拉取数据
WeatherData wd = (WeatherData) o;
// 或使用arg参数获取推送数据
}
}
}
优势:
劣势:
ExecutorService executor = Executors.newCachedThreadPool();
void notifyObservers() {
for (Observer o : observers) {
executor.execute(() -> o.update(...));
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。