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

观察者模式(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.xdnf.cn/news/17706.html

相关文章:

  • 【Leetcode hot 100】76.最小覆盖字串
  • 【HarmonyOS】Window11家庭中文版开启鸿蒙模拟器失败提示未开启Hyoer-V
  • SwiftUI 页面弹窗操作
  • 用飞算JavaAI一键生成电商平台项目:从需求到落地的高效实践
  • 使用免费API开发口播数字人
  • [机器学习]07-基于多层感知机的鸢尾花数据集分类
  • c++中的Lambda表达式详解
  • Java基础07——基本运算符(本文为个人学习笔记,内容整理自哔哩哔哩UP主【遇见狂神说】的公开课程。 > 所有知识点归属原作者,仅作非商业用途分享)
  • k8s+isulad 网络问题
  • 如何使用 AI 大语言模型解决生活中的实际小事情?
  • 【P81 10-7】OpenCV Python【实战项目】——车辆识别、车流统计(图像/视频加载、图像运算与处理、形态学、轮廓查找、车辆统计及显示)
  • 网络协议序列化工具Protobuf
  • 4.1vue3的setup()
  • 2019 GPT2原文 Language Models are Unsupervised Multitask Learners - Reading Notes
  • Kotlin Data Classes 快速上手
  • Qt TCP 客户端对象生命周期与连接断开问题解析
  • 解锁Prompt秘籍:框架、技巧与指标全解析
  • Windows 11操作系统 Git命令执行速度慢
  • SpringMVC基本原理和配置
  • 第2节 如何计算神经网络的参数:AI入门核心逻辑详解
  • pytorch学习笔记-加载现有的网络模型(VGG16)、增加/修改其中的网络层(修改为10分类)
  • 云计算-多服务集群部署实战指南:从JumpServer到Kafka、ZooKeeper 集群部署实操流程
  • 70亿参数让机器人“开窍“:英伟达Cosmos Reason如何让AI理解物理世界
  • 分段锁和限流的间接实现
  • 基于51单片机的手机蓝牙控制8位LED灯亮灭设计
  • Day19 C 语言标准 IO 机制
  • 深度学习——03 神经网络(2)-损失函数
  • 2021 年全国硕士研究生招生考试真题笔记
  • AI时代程序员的进化:从代码工人到创意架构师-优雅草卓伊凡引言:AI浪潮下的职业重构
  • 若依前后端分离版学习笔记(九)——登录和操作日志