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

观察者模式(C++)

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

这种模式的核心是解耦被观察者和观察者,让它们可以独立变化而互不影响。

核心角色

  1. Subject(被观察者/主题)

    • 维护一个观察者列表
    • 提供添加、移除观察者的方法
    • 提供通知所有观察者的方法
  2. Observer(观察者)

    • 定义接收通知的接口
    • 当收到被观察者通知时执行相应操作
  3. ConcreteSubject(具体被观察者)

    • 实现被观察者接口
    • 维护自身状态,状态变化时通知观察者
  4. ConcreteObserver(具体观察者)

    • 实现观察者接口
    • 定义收到通知后的具体处理逻辑

C++实现示例

以下是一个简单的气象站示例,气象站(被观察者)会将温度变化通知给多个显示器(观察者):

#include <iostream>
#include <vector>
#include <string>// 前向声明
class Subject;// 观察者接口
class Observer {
public:virtual ~Observer() = default;virtual void update(float temperature) = 0; // 接收温度更新
};// 被观察者接口
class Subject {
public:virtual ~Subject() = default;virtual void registerObserver(Observer* observer) = 0;  // 注册观察者virtual void removeObserver(Observer* observer) = 0;    // 移除观察者virtual void notifyObservers() = 0;                     // 通知所有观察者
};// 具体被观察者:气象站
class WeatherStation : public Subject {
private:std::vector<Observer*> observers;  // 观察者列表float temperature;                 // 温度状态public:void registerObserver(Observer* observer) override {observers.push_back(observer);}void removeObserver(Observer* observer) override {// 查找并移除观察者for (auto it = observers.begin(); it != observers.end(); ++it) {if (*it == observer) {observers.erase(it);break;}}}void notifyObservers() override {// 通知所有观察者for (auto observer : observers) {observer->update(temperature);}}// 温度变化时调用,触发通知void setTemperature(float temp) {temperature = temp;std::cout << "气象站:温度更新为 " << temperature << "℃" << std::endl;notifyObservers();  // 通知所有观察者}
};// 具体观察者:手机显示器
class PhoneDisplay : public Observer {
private:std::string name;float currentTemp;public:PhoneDisplay(const std::string& n) : name(n), currentTemp(0) {}void update(float temperature) override {currentTemp = temperature;display();}void display() {std::cout << name << " 手机显示:当前温度 " << currentTemp << "℃" << std::endl;}
};// 具体观察者:电脑显示器
class ComputerDisplay : public Observer {
private:float currentTemp;public:ComputerDisplay() : currentTemp(0) {}void update(float temperature) override {currentTemp = temperature;display();}void display() {std::cout << "电脑显示:当前温度 " << currentTemp << "℃," << (currentTemp > 30 ? "天气炎热" : "温度适宜") << std::endl;}
};int main() {// 创建被观察者(气象站)WeatherStation weatherStation;// 创建观察者(显示器)PhoneDisplay phone1("小明的手机");PhoneDisplay phone2("小红的手机");ComputerDisplay computer;// 注册观察者weatherStation.registerObserver(&phone1);weatherStation.registerObserver(&phone2);weatherStation.registerObserver(&computer);// 温度变化,自动通知所有观察者std::cout << "----- 第一次温度变化 -----" << std::endl;weatherStation.setTemperature(25.5f);std::cout << "\n----- 移除小红的手机 -----" << std::endl;weatherStation.removeObserver(&phone2);std::cout << "\n----- 第二次温度变化 -----" << std::endl;weatherStation.setTemperature(32.0f);return 0;
}

代码解析

  1. Observer接口:定义了update方法,所有观察者都必须实现该方法以接收通知。

  2. Subject接口:定义了管理观察者的方法(注册、移除、通知),是被观察者的抽象。

  3. WeatherStation:具体的被观察者,维护温度状态和观察者列表,当温度变化时会调用notifyObservers通知所有注册的观察者。

  4. PhoneDisplay和ComputerDisplay:具体的观察者,实现了update方法,在收到温度更新时会执行各自的显示逻辑。

观察者模式的优缺点

优点

  • 实现了被观察者和观察者的解耦,两者可以独立变化
  • 观察者数量可动态增减,灵活性高
  • 支持广播通信,被观察者的状态变化可同时通知多个观察者

缺点

  • 如果观察者数量过多,通知过程可能耗时较长
  • 观察者之间没有优先级,无法指定通知顺序
  • 可能导致多余的更新通知(即使观察者不需要该状态)

适用场景

  • 当一个对象的状态变化需要触发多个其他对象的更新时(如事件监听)
  • 当需要动态建立对象间的依赖关系时(如订阅/取消订阅功能)
  • 当一个对象必须通知其他对象,但又不知道这些对象是谁时

常见应用:GUI事件处理(按钮点击触发多个响应)、消息通知系统、股票价格更新、RSS订阅等。

http://www.dtcms.com/a/330619.html

相关文章:

  • CV 医学影像分类、分割、目标检测,之【3D肝脏分割】项目拆解
  • Flutter 顶部导航标签组件Tab + TabBar + TabController
  • 汽车生产线白皮书:稳联技术Profinet转Ethernet IP网关通信高效性
  • 中介者模式和观察者模式的区别是什么
  • 三同步舆情处置原则对政务管理有什么影响作用
  • 从实验室到落地:飞算JavaAI水位监测系统的工程化实践
  • 4.2 Vue3中reactive与ref详解及区别
  • 【企业架构】TOGAF概念之四(终结)
  • Day20 Linux 文件 I/O、目录操作及文件链接与 EDID
  • 小杰python(six day)——网络编程
  • 前端Vite介绍(现代化前端构建工具,由尤雨溪开发,旨在显著提升开发体验和构建效率)ES模块(ESM)、与传统Webpack对比、Rollup打包
  • 20250814 最小生成树总结
  • Vue 3 + TypeScript:package.json 示例 / 详细注释说明
  • Linux 上手 UDP Socket 程序编写(含完整具体demo)
  • 如何通过WiFi将文件从安卓设备传输到电脑
  • 计算机视觉(opencv)实战二——图像边界扩展cv2.copyMakeBorder()
  • 机器学习 - Kaggle项目实践(3)Digit Recognizer 手写数字识别
  • 分布式事务、锁、链路追踪
  • 读取数据excel
  • 高效TypeScript开发:VSCode终极配置指南
  • 待办事项小程序开发
  • (第十六期)HTML布局标签详解:div与span的深度解析
  • 【读代码】深度解析 context-engineering-intro:开源上下文工程实践原理与应用
  • 群晖 NAS 影音访问:通过 cpolar 内网穿透服务实现 Nastool 远程管理
  • java集合 之 多列集合
  • Python/Node.js 调用taobao API:构建实时商品详情数据采集服务
  • 使用HalconDotNet实现异步多相机采集与实时处理
  • Mybatis学习笔记(六)
  • 桥接模式C++
  • 成都国际影像产业园:接重庆五一职院实训就业考察