【设计模式】观察者模式
参考文章一文讲清楚观察者模式代码-图#includestdio.h// 前置声明typedefstruct_subject_tsubject_t;typedefstruct_observer_tobserver_t;voidsubject_attach(subject_t*sub,observer_t*obs);voidsubject_detach(subject_t*sub,observer_t*obs);typedefstruct_observer_t{void(*update)(struct_observer_t*,int,int);// 修正函数指针语法struct_observer_t*next;struct_subject_t*subject;// 添加前向声明}observer_t;voidobserver_init(observer_t*obs,subject_t*subject){obs-updateNULL;obs-nextNULL;obs-subjectsubject;subject_attach(subject,obs);}voidobserver_deinit(observer_t*obs)// 移除多余参数{subject_detach(obs-subject,obs);}voidobserver_update(observer_t*obs,inttemp,inthum){if(obs-update!NULL){obs-update(obs,temp,hum);}}// subject_t 结构定义示例struct_subject_t{observer_t*obs;};// 静态初始化主题对象voidsubject_init(subject_t*subject){subject-obsNULL;}// 需要实现的观察者注册函数voidsubject_attach(subject_t*subject,observer_t*obs){if(!subject-obs){subject-obsobs;}else{observer_t*cursubject-obs;while(cur-next)curcur-next;cur-nextobs;}}// 需要实现的观察者注销函数voidsubject_detach(subject_t*subject,observer_t*obs){observer_t**indirectsubject-obs;// 使用二级指针简化操作while(*indirect){if(*indirectobs){*indirectobs-next;// 绕过目标节点obs-nextNULL;// 重置观察者的next指针return;}indirect(*indirect)-next;}}// 数据通知订阅者voidsubject_notify(subject_t*subject,inttemp,inthum){observer_t*_obssubject-obs;while(_obs){observer_update(_obs,temp,hum);_obs_obs-next;}}typedefstruct_display_t{observer_tobs;}display_t;voiddisplay_show(observer_t*obs,inttemp,inthum);// 静态构造函数voiddisplay_init(display_t*display,subject_t*subject){observer_init(display-obs,subject);display-obs.updatedisplay_show;}// 模拟屏幕显示voiddisplay_show(observer_t*obs,inttemp,inthum){printf(temp:%d\n,temp);printf(hum:%d\n,hum);}typedefstruct_ble_t{observer_tobs;}ble_t;voidble_send(observer_t*obs,inttemp,inthum);// 静态构造函数修正变量名错误voidble_init(ble_t*ble,subject_t*subject){observer_init(ble-obs,subject);// 修正 display- → ble-ble-obs.updateble_send;}// 模拟蓝牙发送voidble_send(observer_t*obs,inttemp,inthum){printf(send temp:%d\n,temp);printf(send hum:%d\n,hum);}typedefstruct_sensor_t{subject_tsubject;inttemp;inthum;}sensor_t;// 静态构造函数voidsensor_init(sensor_t*sensor){sensor-temp0;sensor-hum0;subject_init(sensor-subject);}// 模拟温湿度传感器读取数值voidsensor_get(sensor_t*sensor,inttemp,inthum){sensor-temptemp;sensor-humhum;subject_notify(sensor-subject,temp,hum);// 更安全的指针转换}intmain(){// 创建传感器实例sensor_tmy_sensor;sensor_init(my_sensor);// 创建显示设备和蓝牙设备display_tscreen;display_init(screen,(subject_t*)my_sensor);ble_tble_device;ble_init(ble_device,(subject_t*)my_sensor);// 第一次数据更新两个设备都应响应printf( First Update \n);sensor_get(my_sensor,25,60);// 移除蓝牙设备通过反初始化printf(\n Detaching BLE \n);observer_deinit(ble_device.obs);// 第二次数据更新仅显示设备响应printf(\n Second Update \n);sensor_get(my_sensor,26,58);return0;}想法观察者模式是一种消息从下往上的方式类似与回调函数当下面发现了数据变化通知上面。应用层模块的输出通常是上层一步步往下最终底层实现但是底层的数据想要往上传1种通过上层的查询【数据拉模型】2种是通过“通知/回调”的形式上传【数据推模型】回调函数【消费者】上层提供具体回调方法和数据入口【生产者】下层提供抽象回调方法配置attach。典型的就是串口数据接收观察者模式观察者模式利用面向对象的方式讲回调函数接口直接封装起来使用其中“观察者”通常是应用中上层的【消费者】而“被观察对象”通常是下层【生成者】。被观察者通过notify方法将数据上传到观察者端这个过程类似“回调函数”的作用下层应用通知触发上层应用下层被观察者仅通过抽象接口如Observer.update()通知上层不依赖具体实现观察者模式的notify可通知多个观察者一对多而回调通常是一对一的关系观察者模式通过中介如Subject类完全解耦双方回调中调用方需持有被调用方的引用如Callback接口实例观察者模式对比订阅发布模式维度观察者模式 (Observer Pattern)发布-订阅模式 (Pub-Sub Pattern)耦合度松耦合观察者直接依赖被观察者被观察者维护观察者列表完全解耦通过中介传递消息发布者和订阅者互不知晓依赖中介通信方式同步调用立即触发回调的方式立刻执行异步分发通过消息队列/事件总线先登记后处理核心角色被观察者(Subject) 观察者(Observer)发布者(Publisher) 订阅者(Subscriber) 中介(Broker)交互方式被观察者直接调用观察者的方法发布者和订阅者通过主题(Topic)间接通信性能影响可能阻塞观察者处理耗时高吞吐支持削峰填谷典型应用场景GUI事件、单应用组件联动微服务通信、分布式系统事件通知代码实现复杂度简单需手动维护观察者列表较复杂需引入中介系统经典案例JavaObservable/ObserverRedis PUB/SUB、Kafka、RabbitMQ扩展性低新增观察者需修改被观察者高动态增减订阅者无需修改发布者适用规模小型系统或模块内部适合对象间有明确依赖关系、需要实时同步响应的场景如UI更新、状态同步中大型系统或跨服务通信适合需要解耦、异步处理或跨系统通信的场景如微服务、分布式日志依赖倒置原则Dependency Inversion Principle, DIP其核心思想是通过抽象解耦高层模块与低层模块的依赖关系提升系统的灵活性、可维护性和扩展性。依赖倒置原则的定义高层模块不应依赖低层模块两者都应依赖于抽象接口或抽象类。抽象不应依赖细节抽象层定义规范具体实现细节应依赖抽象核心目标通过面向接口编程减少模块间的直接耦合使系统更适应变化。为什么需要依赖倒置传统设计的缺陷高层模块直接调用低层模块导致低层改动时高层必须同步修改如更换数据库需重写业务逻辑代码复用性差并行开发困难如团队需等待底层模块完成才能开发高层依赖倒置的优势解耦高层模块通过抽象接口调用低层功能低层实现可自由替换扩展性新增功能只需实现接口无需修改现有代码符合开闭原则测试友好可通过Mock对象模拟接口独立测试高层逻辑

相关新闻

终极指南:快速掌握TileMapDual插件的7个高效技巧

终极指南:快速掌握TileMapDual插件的7个高效技巧

终极指南:快速掌握TileMapDual插件的7个高效技巧 【免费下载链接】TileMapDual An automatic, real-time dual-grid tileset system for Godot 项目地址: https://gitcode.com/gh_mirrors/ti/TileMapDual 在Godot引擎中创建复杂的瓦片地图,尤其是…

2026/7/30 18:14:14阅读更多 →
Power BI 主题模板:告别单调报表,3分钟打造专业数据可视化

Power BI 主题模板:告别单调报表,3分钟打造专业数据可视化

Power BI 主题模板:告别单调报表,3分钟打造专业数据可视化 【免费下载链接】PowerBI-ThemeTemplates Snippets for assembling Power BI Themes 项目地址: https://gitcode.com/gh_mirrors/po/PowerBI-ThemeTemplates 还在为PowerBI报表的千篇一律…

2026/7/30 18:14:14阅读更多 →
OpenWork高级技巧:自定义插件开发与工作区配置教程

OpenWork高级技巧:自定义插件开发与工作区配置教程

OpenWork高级技巧:自定义插件开发与工作区配置教程 【免费下载链接】openwork The open-source alternative to Claude Cowork (powered by opencode) 项目地址: https://gitcode.com/GitHub_Trending/ope/openwork OpenWork作为开源的Claude Cowork替代方案…

2026/7/30 18:14:14阅读更多 →
Seq2Seq架构解析:从基础原理到现代应用

Seq2Seq架构解析:从基础原理到现代应用

1. 项目概述:从Seq2Seq架构理解大模型基础第一次接触编码器-解码器架构是在2017年翻译任务中,当时被这种"先理解后生成"的机制惊艳到了。Seq2Seq(Sequence to Sequence)作为大语言模型的基础架构之一,其设计…

2026/7/30 19:24:31阅读更多 →
Seq2Seq架构解析:从RNN到Transformer的演进与实践

Seq2Seq架构解析:从RNN到Transformer的演进与实践

1. 项目概述:Seq2Seq架构在大模型中的核心价值在自然语言处理领域,Seq2Seq(Sequence to Sequence)架构一直是机器翻译、文本摘要等任务的基石性技术。这个经典框架由Google在2014年首次提出,如今已成为大模型时代不可或…

2026/7/30 19:24:31阅读更多 →
ChatTTS本地语音合成实战指南:打造专属AI配音系统

ChatTTS本地语音合成实战指南:打造专属AI配音系统

ChatTTS本地语音合成实战指南:打造专属AI配音系统 【免费下载链接】ChatTTS-ui 一个简单的本地网页界面,使用ChatTTS将文字合成为语音,同时支持对外提供API接口。A simple native web interface that uses ChatTTS to synthesize text into s…

2026/7/30 19:24:31阅读更多 →
3步突破:Windows平台上的macOS安装盘制作全攻略

3步突破:Windows平台上的macOS安装盘制作全攻略

3步突破:Windows平台上的macOS安装盘制作全攻略 【免费下载链接】gibMacOS Py2/py3 script that can download macOS components direct from Apple 项目地址: https://gitcode.com/gh_mirrors/gi/gibMacOS 你是否遇到过这样的困境:公司里有多台M…

2026/7/30 19:24:31阅读更多 →
强化学习与WebSocket在PDF解析中的创新应用

强化学习与WebSocket在PDF解析中的创新应用

1. 项目背景与核心价值 这个项目将强化学习技术引入PDF文档解析领域,结合PostIn工具链实现websocket接口的高效调试。PDF解析一直是文档处理中的硬骨头——传统规则引擎面对复杂版式、嵌套表格或扫描件时,准确率往往断崖式下跌。而强化学习通过模拟"…

2026/7/30 19:24:31阅读更多 →
Spring Boot集成Redis四种部署模式详解与实战

Spring Boot集成Redis四种部署模式详解与实战

1. Redis与Spring Boot集成概述Redis作为当前最流行的内存数据库之一,在Spring Boot项目中有着广泛的应用场景。根据不同的业务需求和规模,Redis提供了单机、主从、哨兵和集群四种典型部署模式。我在实际企业级项目开发中发现,90%的配置问题都…

2026/7/30 19:22:31阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/30 15:03:16阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/30 12:22:27阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/30 15:13:02阅读更多 →
3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 🚀 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 你是否曾经因为iOS系统的严格…

2026/7/30 0:00:58阅读更多 →
[GESP202606 四级] 扫雷

[GESP202606 四级] 扫雷

B4557 [GESP202606 四级] 扫雷 https://www.luogu.com.cn/problem/B4557 中国计算机学会(CCF)2026年6月C四级讲解——扫雷 https://www.bilibili.com/video/BV1MCMg6AEXR/ B4557 [GESP202606 四级] 扫雷 https://www.bilibili.com/video/BV1ZKTj6ZEVh/ 2…

2026/7/30 0:00:58阅读更多 →
Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:58阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/30 0:27:26阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/30 4:47:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/30 15:43:46阅读更多 →