跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++ 观察者模式
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{DISPLAYTITLE:C++观察者模式}} '''观察者模式'''(Observer Pattern)是[[设计模式]]中一种行为型模式,用于在对象之间建立一对多的依赖关系,使得当一个对象(主题/被观察者)状态改变时,所有依赖它的对象(观察者)会自动收到通知并更新。该模式广泛应用于事件处理系统、GUI组件交互和实时数据推送等场景。 == 基本概念 == 观察者模式的核心角色包括: * '''Subject(主题)''':维护一个观察者列表,提供添加、删除和通知观察者的接口。 * '''Observer(观察者)''':定义一个更新接口,用于接收主题状态变更的通知。 * '''ConcreteSubject(具体主题)''':实现主题的具体逻辑,存储状态并在状态变化时通知观察者。 * '''ConcreteObserver(具体观察者)''':实现观察者的更新逻辑,对主题状态变化做出响应。 === 模式结构 === <mermaid> classDiagram class Subject { +attach(Observer o) +detach(Observer o) +notify() } class Observer { +update() } class ConcreteSubject { -state +getState() +setState() } class ConcreteObserver { -subject +update() } Subject <|-- ConcreteSubject Observer <|-- ConcreteObserver ConcreteSubject o-- ConcreteObserver </mermaid> == C++实现示例 == 以下是一个简单的C++实现,展示温度传感器(主题)与显示器(观察者)的交互: <syntaxhighlight lang="cpp"> #include <iostream> #include <vector> #include <algorithm> // 前向声明 class Observer; // 主题基类 class Subject { public: virtual void attach(Observer* o) = 0; virtual void detach(Observer* o) = 0; virtual void notify() = 0; }; // 观察者基类 class Observer { public: virtual void update(float temperature) = 0; }; // 具体主题:温度传感器 class TemperatureSensor : public Subject { private: std::vector<Observer*> observers; float temperature; public: void attach(Observer* o) override { observers.push_back(o); } void detach(Observer* o) override { observers.erase(std::remove(observers.begin(), observers.end(), o), observers.end()); } void notify() override { for (auto* o : observers) { o->update(temperature); } } void setTemperature(float temp) { temperature = temp; notify(); // 状态变化时通知观察者 } }; // 具体观察者:温度显示器 class TemperatureDisplay : public Observer { public: void update(float temperature) override { std::cout << "Temperature updated: " << temperature << "°C\n"; } }; int main() { TemperatureSensor sensor; TemperatureDisplay display; sensor.attach(&display); sensor.setTemperature(23.5); // 输出:Temperature updated: 23.5°C sensor.setTemperature(25.0); // 输出:Temperature updated: 25°C return 0; } </syntaxhighlight> === 代码解释 === 1. '''Subject''' 和 '''Observer''' 是抽象基类,定义接口规范。 2. '''TemperatureSensor''' 是具体主题,维护观察者列表并在温度变化时调用 `notify()`。 3. '''TemperatureDisplay''' 是具体观察者,实现 `update()` 方法以响应状态变化。 4. 在 `main()` 中,传感器与显示器通过观察者模式解耦,传感器无需直接调用显示器的接口。 == 实际应用场景 == 观察者模式在以下场景中非常有用: * '''GUI事件处理''':如按钮点击事件通知多个监听器。 * '''发布-订阅系统''':如消息队列中的生产者-消费者模型。 * '''游戏开发''':角色状态变化触发UI或AI的更新。 === 案例:股票价格通知 === 假设有一个股票交易系统,当股票价格变化时,需要通知所有订阅该股票的投资者: <syntaxhighlight lang="cpp"> // 省略基类定义(与温度示例类似) class Stock : public Subject { private: std::string symbol; double price; public: Stock(const std::string& s, double p) : symbol(s), price(p) {} void setPrice(double p) { price = p; notify(); } std::string getSymbol() const { return symbol; } double getPrice() const { return price; } }; class Investor : public Observer { private: std::string name; public: Investor(const std::string& n) : name(n) {} void update(double price) override { std::cout << name << " notified: Price changed to $" << price << "\n"; } }; // 使用示例 int main() { Stock apple("AAPL", 150.0); Investor alice("Alice"), bob("Bob"); apple.attach(&alice); apple.attach(&bob); apple.setPrice(155.5); // 输出两条通知 } </syntaxhighlight> == 进阶讨论 == === 推模型 vs 拉模型 === * '''推模型''':主题将详细数据通过 `update()` 参数传递给观察者(如上述示例)。 * '''拉模型''':观察者通过主题的接口主动获取数据(需在 `update()` 中调用 `getState()`)。 === 线程安全问题 === 在多线程环境中,需对观察者列表的修改和遍历加锁(如使用 `std::mutex`)。 == 总结 == 观察者模式通过解耦主题和观察者,增强了代码的灵活性和可维护性。C++中可通过继承和纯虚函数实现该模式,适用于需要动态响应用户交互或数据变化的系统。 [[Category:编程语言]] [[Category:C++]] [[Category:C++ 高级主题]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)