C++ 观察者模式

🎯 观察者模式协作关系说明

01、资源获取

>>>

通过网盘分享的文件:CXX观察者模式observer_pattern

链接: https://pan.baidu.com/s/15_ev6Y-ZL0cQjrfIrA7Y9Q?pwd=ubrb 提取码: ubrb

  1. 📖 模式概述

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

  1. 🎭 核心角色

|-------------------------|----------------------|---------------------------------------|
| 🎭 角色 | 📋 职责 | 💻 实现类 |
| Subject(被观察者) | 管理观察者列表,提供注册、移除和通知方法 | Subject |
| Observer(观察者) | 定义更新接口,用于接收被观察者的通知 | Observer |
| ConcreteSubject(具体被观察者) | 实现被观察者接口,维护具体状态 | Subject (本示例直接使用Subject作为具体被观察者) |
| ConcreteObserver(具体观察者) | 实现观察者接口,处理被观察者的通知 | ConcreteObserverA 、 ConcreteObserverB |

  1. 🗺️ 协作关系思维导图
  1. 🔄 详细协作流程

4.1 🚀 初始化阶段

客户端创建被观察者对象

客户端创建多个观察者对象

客户端调用被观察者的attach()方法,将观察者注册到被观察者的观察者列表中

4.2 📢 通知阶段

客户端调用被观察者的setState()方法,修改被观察者的状态

setState()方法内部调用notify()方法,开始通知所有观察者

notify()方法遍历观察者列表,依次调用每个观察者的update()方法

每个观察者的update()方法被调用,执行各自的业务逻辑

4.3 ⚡ 动态调整阶段

客户端可以随时调用被观察者的detach()方法,将观察者从列表中移除

移除后的观察者将不再收到被观察者的通知

客户端也可以随时调用attach()方法,重新注册观察者

  1. 💻 代码执行流程

以main.cpp为例,详细执行流程如下:

  1. 🔗 关键方法调用链

6.1 ➕ 注册观察者

Client.attach(observer) → Subject.attach() → 观察者列表.push_back(observer)

6.2 📣 状态变化通知

Client.setState(state) → Subject.setState() → Subject.notify() → 遍历观察者列表 → 每个Observer.update(state)

6.3 ➖ 移除观察者

Client.detach(observer) → Subject.detach() → 观察者列表.remove(observer)

  1. ✨ 设计优势

🔓 松耦合:被观察者和观察者之间通过接口通信,降低了耦合度

📈 可扩展性:可以轻松添加新的观察者类型,无需修改被观察者代码

⚡ 触发机制:实现了事件驱动的编程模型,状态变化自动触发更新

🎯 灵活性:可以动态添加和移除观察者

  1. 🎪 应用场景

🖥️ 图形界面中的事件处理系统

📬 消息队列和发布-订阅系统

📊 数据监控和日志系统

⚙️ 配置文件更新通知

📈 股票价格实时更新

  1. 🆚 与其他模式的区别

|---------|---------------------|
| 📊 模式 | 📝 主要区别 |
| 观察者模式 | 一对多关系,被观察者主动通知观察者 |
| 发布-订阅模式 | 引入中间层(消息队列),观察者被动订阅 |
| 中介者模式 | 多对多关系,通过中介者协调对象间通信 |
| 迭代器模式 | 用于遍历集合,不涉及事件通知 |

  1. 🔧 代码优化建议

🔒 线程安全:当前实现不是线程安全的,在多线程环境下需要添加互斥锁保护观察者列表

🔄 避免循环依赖:注意避免观察者和被观察者之间的循环引用

⏱️ 异步通知:对于耗时的观察者更新,可以考虑使用异步通知机制

🎯 通知优先级:可以为观察者添加优先级,按照优先级顺序通知

📦 批量通知:对于频繁状态变化的场景,可以考虑批量通知,减少通知次数

  1. 📝 总结

观察者模式是一种经典的设计模式,它实现了对象间的高效通信和状态同步。通过合理使用观察者模式,可以提高系统的可扩展性、松耦合性和可维护性。本示例展示了观察者模式的基本实现和使用方法,希望能帮助您理解和应用这一设计模式。

相关推荐
无心水16 小时前
【任务调度:数据库锁 + 线程池实战】3、 从 SELECT 到 UPDATE:深入理解 SKIP LOCKED 的锁机制与隔离级别
java·分布式·科技·spring·架构
想放学的刺客17 小时前
整理了120道单片机嵌入式面试题与答案,覆盖了硬件电路和C语言等核心领域。
c语言·c++·stm32·单片机·嵌入式硬件·mcu·51单片机
编程小白gogogo17 小时前
苍穹外卖图片不显示解决教程
java·spring boot
舟舟亢亢17 小时前
算法总结——二叉树【hot100】(上)
java·开发语言·算法
百锦再17 小时前
Java中的char、String、StringBuilder与StringBuffer 深度详解
java·开发语言·python·struts·kafka·tomcat·maven
普通网友18 小时前
多协议网络库设计
开发语言·c++·算法
努力努力再努力wz18 小时前
【Linux网络系列】:TCP 的秩序与策略:揭秘传输层如何从不可靠的网络中构建绝对可靠的通信信道
java·linux·开发语言·数据结构·c++·python·算法
汉克老师19 小时前
GESP2024年3月认证C++二级( 第二部分判断题(1-10))
c++·循环结构·分支结构·gesp二级·gesp2级
daxi15019 小时前
C语言从入门到进阶——第9讲:函数递归
c语言·开发语言·c++·算法·蓝桥杯
yy.y--19 小时前
Java数组逆序读写文件实战
java·开发语言