当前位置: 首页 > ops >正文

深入理解设计模式之观察者模式

深入理解设计模式之观察者模式(Observer Pattern)

一、什么是观察者模式?

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

通俗地说,观察者模式就是“发布-订阅”模式,主题(被观察者)负责发布消息,观察者负责订阅并响应消息。

二、观察者模式的结构

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

  1. Subject(主题/被观察者):负责维护观察者列表,提供添加、删除观察者的方法,并在自身状态变化时通知所有观察者。
  2. Observer(观察者):定义响应通知的接口。
  3. ConcreteSubject(具体主题):实现主题的具体逻辑。
  4. ConcreteObserver(具体观察者):实现观察者的具体响应逻辑。

三、观察者模式的优缺点

优点

  • 解耦:主题和观察者之间是抽象耦合,便于独立扩展和复用。
  • 动态联动:支持动态添加、删除观察者,灵活性高。
  • 广播机制:主题变化时可通知所有观察者,实现广播通信。

缺点

  • 通知无顺序:通知观察者的顺序不可控,可能带来不确定性。
  • 性能问题:观察者过多时,通知会耗时,影响性能。
  • 循环依赖:可能导致循环调用,需注意防止。

四、典型应用场景

  • 事件系统(如GUI事件监听、消息订阅等)
  • 订阅-发布系统(如新闻订阅、微信公众号推送等)
  • 数据模型与视图联动(如MVC模式中的Model-View)

五、Java实现示例

下面以“气象站”推送天气数据为例,演示观察者模式的实现。

1. 观察者接口

// 观察者接口
public interface Observer {void update(float temperature, float humidity, float pressure);
}

2. 主题接口

// 主题接口
public interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}

3. 具体主题(气象站)

import java.util.ArrayList;
import java.util.List;// 具体主题
public class WeatherData implements Subject {private List<Observer> observers = new ArrayList<>();private float temperature;private float humidity;private float pressure;@Overridepublic void registerObserver(Observer o) {observers.add(o);}@Overridepublic void removeObserver(Observer o) {observers.remove(o);}@Overridepublic void notifyObservers() {for (Observer o : observers) {o.update(temperature, humidity, pressure);}}// 当气象数据更新时调用public void setMeasurements(float temperature, float humidity, float pressure) {this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;notifyObservers();}
}

4. 具体观察者

// 具体观察者
public class CurrentConditionsDisplay implements Observer {@Overridepublic void update(float temperature, float humidity, float pressure) {System.out.println("当前天气:温度=" + temperature + "℃, 湿度=" + humidity + "%, 气压=" + pressure + "hPa");}
}public class ForecastDisplay implements Observer {@Overridepublic void update(float temperature, float humidity, float pressure) {System.out.println("天气预报:温度=" + (temperature + 1) + "℃, 湿度=" + (humidity - 2) + "%, 气压=" + (pressure + 1) + "hPa");}
}

5. 客户端代码

public class Client {public static void main(String[] args) {WeatherData weatherData = new WeatherData();Observer currentDisplay = new CurrentConditionsDisplay();Observer forecastDisplay = new ForecastDisplay();weatherData.registerObserver(currentDisplay);weatherData.registerObserver(forecastDisplay);// 模拟气象数据变化weatherData.setMeasurements(25.0f, 65.0f, 1013.0f);System.out.println("----");weatherData.setMeasurements(28.0f, 70.0f, 1012.0f);}
}

6. 输出结果

当前天气:温度=25.0℃, 湿度=65.0%, 气压=1013.0hPa
天气预报:温度=26.0℃, 湿度=63.0%, 气压=1014.0hPa
----
当前天气:温度=28.0℃, 湿度=70.0%, 气压=1012.0hPa
天气预报:温度=29.0℃, 湿度=68.0%, 气压=1013.0hPa

六、总结

观察者模式是一种非常常用的设计模式,广泛应用于事件驱动、消息推送、数据联动等场景。它实现了对象之间的解耦,让系统更加灵活和可扩展。但在使用时也要注意性能和循环依赖等问题。


如需源码或有其他设计模式问题,欢迎留言交流!

http://www.xdnf.cn/news/10381.html

相关文章:

  • 59、干系人概述
  • Windows系统时间怎么设置
  • Centos7 中Gunicorn的安装配置
  • Docker 在云环境中的部署:AWS/ECS 与 Azure/AKS 的实践对比
  • 自动驾驶系统研发系列—激光雷达感知延迟:自动驾驶安全的隐形隐患?
  • opencv使用经典bug
  • OD 算法题 B卷【文件目录大小】
  • 基于ssm+mysql的大创项目申报管理系统(含LW+PPT+源码+系统演示视频+安装说明)
  • 历年中山大学计算机保研上机真题
  • java swing 晃动鼠标改变背景颜色
  • PySide6 GUI 学习笔记——常用类及控件使用方法(标签控件QLabel)
  • Git初识Git安装
  • Spring Boot,两种配置文件
  • LeetCode 39.组合总和:回溯法与剪枝优化的完美结合
  • CCPC dongbei 2025 F
  • 组件化:软件工程化的基础
  • 接口安全SOAPOpenAPIRESTful分类特征导入项目联动检测
  • 树莓派3B小练习
  • IT技术文章汇总
  • 美业+智能体,解锁行业转化新密码(2/6)
  • 大白话 Seata 分布式事务浅析,详解TCC模式
  • 腾讯位置商业授权行政区划开发指南
  • Codeforces Round 1028 (Div. 2) B. Gellyfish and Baby‘s Breath
  • Nginx反向代理
  • NodeJS全栈开发面试题讲解——P12高性能场景题
  • Chorme如何对于youtube视频进行画中画背景播放?
  • 多模态AI的企业应用场景:视觉+语言模型的商业价值挖掘
  • 8天Python从入门到精通【itheima】-62~63
  • 结合源码分析Redis的内存回收和内存淘汰机制,LRU和LFU是如何进行计算的?
  • 深度学习|pytorch基本运算-乘除法和幂运算