观察者模式

1. 模式定义

观察者模式(Observer Pattern)定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

2. 核心组件

2.1 Subject(主题/被观察者)

java 复制代码
public interface Subject {
    void registerObserver(Observer observer);    // 注册观察者
    void removeObserver(Observer observer);      // 移除观察者
    void notifyObservers();                      // 通知所有观察者
}

2.2 Observer(观察者)

java 复制代码
public interface Observer {
    void update(Object data);  // 接收更新通知
}

3. 完整实现示例

3.1 具体主题类

java 复制代码
import java.util.*;

public class WeatherStation implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;
    
    public WeatherStation() {
        observers = new ArrayList<>();
    }
    
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
        System.out.println("观察者已注册");
    }
    
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
        System.out.println("观察者已移除");
    }
    
    @Override
    public void notifyObservers() {
        WeatherData data = new WeatherData(temperature, humidity, pressure);
        for (Observer observer : observers) {
            observer.update(data);
        }
    }
    
    // 天气数据改变时调用
    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
    
    private void measurementsChanged() {
        notifyObservers();
    }
    
    // 天气数据类
    public static class WeatherData {
        private final float temperature;
        private final float humidity;
        private final float pressure;
        
        public WeatherData(float temperature, float humidity, float pressure) {
            this.temperature = temperature;
            this.humidity = humidity;
            this.pressure = pressure;
        }
        
        // getters
        public float getTemperature() { return temperature; }
        public float getHumidity() { return humidity; }
        public float getPressure() { return pressure; }
    }
}

3.2 具体观察者类

java 复制代码
// 当前天气显示板
public class CurrentConditionsDisplay implements Observer {
    private String name;
    
    public CurrentConditionsDisplay(String name) {
        this.name = name;
    }
    
    @Override
    public void update(Object data) {
        if (data instanceof WeatherStation.WeatherData) {
            WeatherStation.WeatherData weatherData = (WeatherStation.WeatherData) data;
            display(weatherData);
        }
    }
    
    private void display(WeatherStation.WeatherData data) {
        System.out.println(name + " - 当前天气:");
        System.out.println("温度:" + data.getTemperature() + "°C");
        System.out.println("湿度:" + data.getHumidity() + "%");
        System.out.println("气压:" + data.getPressure() + " hPa");
        System.out.println("------------------------");
    }
}

// 统计显示板
public class StatisticsDisplay implements Observer {
    private List<Float> temperatures = new ArrayList<>();
    
    @Override
    public void update(Object data) {
        if (data instanceof WeatherStation.WeatherData) {
            WeatherStation.WeatherData weatherData = (WeatherStation.WeatherData) data;
            temperatures.add(weatherData.getTemperature());
            display();
        }
    }
    
    private void display() {
        float avg = (float) temperatures.stream().mapToDouble(Float::doubleValue).average().orElse(0);
        float max = temperatures.stream().max(Float::compare).orElse(0f);
        float min = temperatures.stream().min(Float::compare).orElse(0f);
        
        System.out.println("温度统计:");
        System.out.println("平均温度:" + String.format("%.1f", avg) + "°C");
        System.out.println("最高温度:" + max + "°C");
        System.out.println("最低温度:" + min + "°C");
        System.out.println("------------------------");
    }
}

4. 使用示例

java 复制代码
public class WeatherStationDemo {
    public static void main(String[] args) {
        // 创建天气站
        WeatherStation weatherStation = new WeatherStation();
        
        // 创建观察者
        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay("显示板1");
        CurrentConditionsDisplay currentDisplay2 = new CurrentConditionsDisplay("显示板2");
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay();
        
        // 注册观察者
        weatherStation.registerObserver(currentDisplay);
        weatherStation.registerObserver(currentDisplay2);
        weatherStation.registerObserver(statisticsDisplay);
        
        // 更新天气数据
        System.out.println("=== 第一次天气更新 ===");
        weatherStation.setMeasurements(25.5f, 65f, 1013.2f);
        
        System.out.println("\n=== 第二次天气更新 ===");
        weatherStation.setMeasurements(28.0f, 70f, 1012.8f);
        
        // 移除一个观察者
        weatherStation.removeObserver(currentDisplay2);
        
        System.out.println("\n=== 第三次天气更新(移除显示板2后) ===");
        weatherStation.setMeasurements(22.3f, 60f, 1014.1f);
    }
}
相关推荐
o0向阳而生0o4 天前
107、23种设计模式之观察者模式(16/23)
观察者模式·设计模式
青草地溪水旁11 天前
设计模式(C++)详解——观察者模式(Observer)(1)
c++·观察者模式·设计模式
星空寻流年11 天前
设计模式第六章(观察者模式)
网络·观察者模式·设计模式
大飞pkz12 天前
【设计模式】观察者模式
开发语言·观察者模式·设计模式·c#
charlie11451419114 天前
精读 C++20 设计模式:行为型设计模式——观察者模式
c++·学习·观察者模式·设计模式·程序设计·c++20
青草地溪水旁14 天前
设计模式(C++)详解——观察者模式(Observer)(2)
c++·观察者模式·设计模式
PaoloBanchero18 天前
Unity 虚拟仿真实验中设计模式的使用 —— 观察者模式(Observer Pattern)
观察者模式·unity·设计模式
Chan1620 天前
【 设计模式 | 行为型模式 观察者模式 】
java·spring boot·后端·spring·观察者模式·设计模式·idea
宁静致远20211 个月前
【C++设计模式】第三篇:观察者模式(别名:发布-订阅模式、模型-视图模式、源-监听器模式)
c++·观察者模式·设计模式