观察者模式通过定义Subject和Observer接口实现对象间一对多的依赖关系,当Subject状态变化时自动通知所有Observer。示例中使用shared_ptr管理观察者列表,ConcreteSubject在事件发生时调用notify通知所有注册的ConcreteObserver,输出对应消息,支持动态注册与注销,具备良好扩展性,适用于事件处理系统。
在c++中实现观察者模式(Observer Pattern)的核心是建立一种一对多的依赖关系,使得当一个对象(被观察者)状态发生变化时,所有依赖它的对象(观察者)都能自动收到通知。这种机制常用于事件处理系统、GUI组件通信、消息订阅等场景。
观察者模式基本结构
观察者模式包含两个主要角色:
- Subject(被观察者):维护观察者列表,提供注册、注销和通知接口。
- Observer(观察者):定义一个更新接口,被通知时执行相应操作。
下面是一个简洁、可复用的C++实现示例:
1. 定义抽象观察者和被观察者接口
#include <iostream> #include <vector> #include <algorithm> #include <memory> // 抽象观察者 class Observer { public: virtual ~Observer() = default; virtual void update(const std::string& message) = 0; }; // 抽象被观察者 class Subject { public: virtual ~Subject() = default; virtual void attach(std::shared_ptr<Observer> observer) = 0; virtual void detach(std::shared_ptr<Observer> observer) = 0; virtual void notify(const std::string& message) = 0; };
2. 实现具体被观察者(事件源)
具体被观察者持有一个观察者列表,并在状态变化时调用 notify 发送消息。
立即学习“C++免费学习笔记(深入)”;
class ConcreteSubject : public Subject { private: std::vector<std::shared_ptr<Observer>> observers; public: void attach(std::shared_ptr<Observer> observer) override { observers.push_back(observer); } void detach(std::shared_ptr<Observer> observer) override { observers.erase( std::remove(observers.begin(), observers.end(), observer), observers.end() ); } void notify(const std::string& message) override { for (const auto& obs : observers) { obs->update(message); } } // 模拟事件触发 void eventHappened(const std::string& event) { std::cout << "[Subject] Event occurred: " << event << "n"; notify(event); } };
3. 实现具体观察者
每个观察者实现自己的 update 逻辑,响应通知。
class ConcreteObserver : public Observer { private: std::string name; public: ConcreteObserver(const std::string& n) : name(n) {} void update(const std::string& message) override { std::cout << "[Observer " << name << "] Received: " << message << "n"; } };
4. 使用示例
将观察者注册到被观察者,触发事件后自动通知所有观察者。
int main() { auto subject = std::make_shared<ConcreteSubject>(); auto obs1 = std::make_shared<ConcreteObserver>("Alice"); auto obs2 = std::make_shared<ConcreteObserver>("Bob"); subject->attach(obs1); subject->attach(obs2); subject->eventHappened("User logged in"); subject->detach(obs2); subject->eventHappened("Data updated"); return 0; }
输出结果:
[Subject] Event occurred: User logged in [Observer Alice] Received: User logged in [Observer Bob] Received: User logged in [Subject] Event occurred: Data updated [Observer Alice] Received: Data updated
扩展建议
- 使用 std::weak_ptr 避免循环引用或悬挂指针(特别是在观察者生命周期短于被观察者时)。
- 支持不同类型的消息(如枚举事件类型),让观察者选择性处理。
- 引入线程安全机制(如互斥锁)用于多线程环境。
- 使用函数对象(std::function)实现更灵活的回调机制,适合轻量级事件系统。
基本上就这些。这个结构清晰、易于扩展,适用于大多数C++项目中的事件通知需求。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END