观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象的状态变化。当主题对象的状态发生变化时,它会通知所有注册的观察者对象,使得观察者对象能够自动更新自己。

观察者模式主要包含以下几个角色:

  1. 主题(Subject):被观察的对象,维护一组观察者,并提供添加、删除观察者以及通知观察者的方法。
  2. 观察者(Observer):定义了一个更新接口,用于在主题状态发生变化时接收通知。
  3. 具体主题(ConcreteSubject):具体的被观察对象,实现主题接口,维护了一个观察者列表,并在状态变化时通知观察者。
  4. 具体观察者(ConcreteObserver):具体的观察者对象,实现观察者接口,当接收到主题通知时,执行相应的更新操作。

观察者模式可以实现松耦合的设计,主题和观察者之间的依赖关系降低了耦合度,使得主题和观察者可以独立地进行扩展和变化。

示例:

假设我们有一个气象站程序,其中包含一个气象数据主题(WeatherDataSubject)和两个观察者(CurrentConditionsDisplay、StatisticsDisplay),这两个观察者用于显示不同的气象数据。

java 复制代码
package com.example.demo.guanchazhe;

import java.util.ArrayList;
import java.util.List;

// 主题:气象数据
interface WeatherDataSubject {
    void registerObserver(WeatherDataObserver observer);
    void removeObserver(WeatherDataObserver observer);
    void notifyObservers();
    void setMeasurements(float temperature, float humidity, float pressure);
}

// 观察者:气象数据显示
interface WeatherDataObserver {
    void update(float temperature, float humidity, float pressure);
}

// 具体主题:气象数据
class WeatherData implements WeatherDataSubject {
    private List<WeatherDataObserver> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() {
        observers = new ArrayList<>();
    }

    @Override
    public void registerObserver(WeatherDataObserver observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(WeatherDataObserver observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (WeatherDataObserver 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();
    }

    private void measurementsChanged() {
        notifyObservers();
    }
}

// 具体观察者:当前气象数据显示
class CurrentConditionsDisplay implements WeatherDataObserver {
    @Override
    public void update(float temperature, float humidity, float pressure) {
        System.out.println("当前气象数据:温度 " + temperature + "°C, 湿度 " + humidity + "%, 气压 " + pressure + " hPa");
    }
}

// 具体观察者:气象数据统计显示
class StatisticsDisplay implements WeatherDataObserver {
    @Override
    public void update(float temperature, float humidity, float pressure) {
        // 这里可以实现气象数据的统计分析和显示
        System.out.println("气象数据统计显示:统计分析中...");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        WeatherDataSubject weatherData = new WeatherData();
        WeatherDataObserver currentDisplay = new CurrentConditionsDisplay();
        WeatherDataObserver statisticsDisplay = new StatisticsDisplay();

        weatherData.registerObserver(currentDisplay);
        weatherData.registerObserver(statisticsDisplay);

        // 模拟气象数据变化
        weatherData.setMeasurements(25.5f, 65f, 1013.2f);
    }
}

在上面的示例中,我们定义了主题接口WeatherDataSubject和观察者接口WeatherDataObserver。然后,实现了一个具体主题类WeatherData,它维护了一个观察者列表,并在气象数据变化时通知所有注册的观察者。还实现了两个具体观察者类CurrentConditionsDisplayStatisticsDisplay,它们分别用于显示当前气象数据和进行气象数据统计。

通过观察者模式,我们可以实现主题和观察者之间的解耦,使得主题和观察者可以独立地进行扩展和变化。当气象数据发生变化时,具体主题会通知所有注册的观察者,观察者会自动更新自己的显示内容。这样可以方便地添加新的观察者来显示不同的气象数据,而不需要修改主题的代码。

相关推荐
ldj202014 分钟前
SpringBoot为什么使用new RuntimeException() 来获取调用栈?
java·spring boot·后端
超龄超能程序猿15 分钟前
Spring 应用中 Swagger 2.0 迁移 OpenAPI 3.0 详解:配置、注解与实践
java·spring boot·后端·spring·spring cloud
风象南27 分钟前
SpringBoot配置属性热更新的轻量级实现
java·spring boot·后端
洛阳泰山28 分钟前
Spring Boot 整合 Nacos 实战教程:服务注册发现与配置中心详解
java·spring boot·后端·nacos
Y40900128 分钟前
C语言转Java语言,相同与相异之处
java·c语言·开发语言·笔记
YuTaoShao29 分钟前
【LeetCode 热题 100】994. 腐烂的橘子——BFS
java·linux·算法·leetcode·宽度优先
布朗克16829 分钟前
java常见的jvm内存分析工具
java·jvm·数据库
都叫我大帅哥2 小时前
深入浅出 Resilience4j:Java 微服务的“免疫系统”实战指南
java·spring cloud
Cao_Shixin攻城狮4 小时前
Flutter运行Android项目时显示java版本不兼容(Unsupported class file major version 65)的处理
android·java·flutter
Dcs6 小时前
还在用 Arrays.hashCode?Java 自己也能写出更快的版本!
java