C++20观察者模式:现代实现技巧
观察者模式概述
观察者模式是一种行为型设计模式,允许对象(称为观察者)订阅另一个对象(称为主题)的状态变化。当主题状态发生改变时,所有注册的观察者会自动收到通知并更新。这种模式解耦了主题与观察者,使它们可以独立变化。
在C++20中,观察者模式可以通过现代语言特性(如std::function、lambda表达式和协程)更简洁地实现。
模式结构
-
Subject(主题)
维护一个观察者列表,提供注册(attach)和注销(detach)方法,以及通知观察者的notify方法。 -
Observer(观察者)
定义更新接口(如update),供主题在状态变化时调用。 -
ConcreteSubject(具体主题)
存储具体状态,状态变化时调用notify。 -
ConcreteObserver(具体观察者)
实现update方法,根据主题状态执行具体逻辑。
C++20 实现示例
#include <functional>
#include <vector>
#include <iostream>
class Subject {
private:
std::vector<std::function<void(int)>> observers_;
int state_;
public:
void attach(const std::function<void(int)>& observer) {
observers_.push_back(observer);
}
void setState(int state) {
state_ = state;
notify();
}
void notify() {
for (const auto& observer : observers_) {
observer(state_);
}
}
};
int main() {
Subject subject;
// Lambda表达式作为观察者
subject.attach([](int state) {
std::cout << "Observer 1: State updated to " << state << std::endl;
});
subject.attach([](int state) {
std::cout << "Observer 2: State updated to " << state << std::endl;
});
subject.setState(42); // 触发通知
}
现代C++20特性优化
-
使用
std::function与Lambda
避免继承,通过函数对象实现松耦合,简化观察者注册。 -
协程支持(C++20)
若需异步通知,可通过协程实现非阻塞观察者:
#include <coroutine>
struct Awaiter {
bool await_ready() const { return false; }
void await_suspend(std::coroutine_handle<> h) { /* 保存h供后续恢复 */ }
void await_resume() {}
};
// 观察者协程
auto asyncObserver() -> std::future<void> {
co_await Awaiter{}; // 等待通知
std::cout << "Async update received" << std::endl;
}
- RAII自动注销
利用智能指针管理观察者生命周期:
class ScopedObserver {
Subject& subject_;
std::function<void(int)> observer_;
public:
ScopedObserver(Subject& s, std::function<void(int)> obs)
: subject_(s), observer_(obs) { subject_.attach(observer_); }
~ScopedObserver() { /* 自动注销逻辑 */ }
};
应用场景
- GUI事件处理:按钮点击通知多个控件。
- 发布-订阅系统:消息队列中的事件广播。
- 状态监控:如传感器数据变化触发多个处理模块。
优缺点分析
优点
- 符合开闭原则:新增观察者无需修改主题。
- 运行时动态建立对象间关系。
缺点
- 通知顺序不可控,可能引发意外依赖。
- 频繁通知可能影响性能,需考虑异步或批量更新。
总结
观察者模式在C++20中通过现代特性获得了更简洁、灵活的实现方式。结合lambda、协程和RAII等技术,可以构建高效且易于维护的事件驱动系统。实际应用中需权衡性能与解耦需求,必要时引入中间件(如消息队列)进一步优化。
5G.okacbd182.asia/PoSt/1123_436271.HtM
5G.okacbd183.asia/PoSt/1123_259832.HtM
5G.okacbd184.asia/PoSt/1123_463953.HtM
5G.okacbd185.asia/PoSt/1123_162496.HtM
5G.okacbd186.asia/PoSt/1123_185748.HtM
5G.okacbd187.asia/PoSt/1123_174808.HtM
5G.okacbd188.asia/PoSt/1123_853647.HtM
5G.okacbd190.asia/PoSt/1123_145943.HtM
5G.okacbd191.asia/PoSt/1123_473333.HtM
5G.okacbd192.asia/PoSt/1123_093314.HtM
5G.okacbd182.asia/PoSt/1123_130175.HtM
5G.okacbd183.asia/PoSt/1123_973555.HtM
5G.okacbd184.asia/PoSt/1123_198048.HtM
5G.okacbd185.asia/PoSt/1123_012805.HtM
5G.okacbd186.asia/PoSt/1123_169701.HtM
5G.okacbd187.asia/PoSt/1123_508957.HtM
5G.okacbd188.asia/PoSt/1123_882750.HtM
5G.okacbd190.asia/PoSt/1123_063885.HtM
5G.okacbd191.asia/PoSt/1123_962525.HtM
5G.okacbd192.asia/PoSt/1123_631696.HtM
5G.okacbd182.asia/PoSt/1123_218047.HtM
5G.okacbd183.asia/PoSt/1123_057662.HtM
5G.okacbd184.asia/PoSt/1123_434189.HtM
5G.okacbd185.asia/PoSt/1123_310910.HtM
5G.okacbd186.asia/PoSt/1123_457607.HtM
5G.okacbd187.asia/PoSt/1123_604660.HtM
5G.okacbd188.asia/PoSt/1123_768501.HtM
5G.okacbd190.asia/PoSt/1123_170934.HtM
5G.okacbd191.asia/PoSt/1123_220506.HtM
5G.okacbd192.asia/PoSt/1123_612180.HtM
5G.okacbd182.asia/PoSt/1123_545137.HtM
5G.okacbd183.asia/PoSt/1123_763289.HtM
5G.okacbd184.asia/PoSt/1123_341849.HtM
5G.okacbd185.asia/PoSt/1123_115564.HtM
5G.okacbd186.asia/PoSt/1123_721832.HtM
5G.okacbd187.asia/PoSt/1123_760897.HtM
5G.okacbd188.asia/PoSt/1123_924278.HtM
5G.okacbd190.asia/PoSt/1123_218072.HtM
5G.okacbd191.asia/PoSt/1123_280382.HtM
5G.okacbd192.asia/PoSt/1123_821488.HtM
5G.okacbd182.asia/PoSt/1123_792432.HtM
5G.okacbd183.asia/PoSt/1123_880667.HtM
5G.okacbd184.asia/PoSt/1123_325830.HtM
5G.okacbd185.asia/PoSt/1123_292421.HtM
5G.okacbd186.asia/PoSt/1123_461225.HtM
5G.okacbd187.asia/PoSt/1123_439678.HtM
5G.okacbd188.asia/PoSt/1123_350300.HtM
5G.okacbd190.asia/PoSt/1123_451000.HtM
5G.okacbd191.asia/PoSt/1123_093078.HtM
5G.okacbd192.asia/PoSt/1123_859594.HtM
5G.okacbd182.asia/PoSt/1123_612676.HtM
5G.okacbd183.asia/PoSt/1123_906832.HtM
5G.okacbd184.asia/PoSt/1123_474731.HtM
5G.okacbd185.asia/PoSt/1123_346217.HtM
5G.okacbd186.asia/PoSt/1123_017210.HtM
5G.okacbd187.asia/PoSt/1123_012947.HtM
5G.okacbd188.asia/PoSt/1123_129808.HtM
5G.okacbd190.asia/PoSt/1123_709425.HtM
5G.okacbd191.asia/PoSt/1123_881266.HtM
5G.okacbd192.asia/PoSt/1123_657828.HtM
5G.okacbd193.asia/PoSt/1123_857917.HtM
5G.okacbd194.asia/PoSt/1123_176736.HtM
5G.okacbd195.asia/PoSt/1123_452236.HtM
5G.okacbd196.asia/PoSt/1123_003501.HtM
5G.okacbd197.asia/PoSt/1123_648880.HtM
5G.okacbd198.asia/PoSt/1123_559911.HtM
5G.okacbd199.asia/PoSt/1123_630168.HtM
5G.okacbd200.asia/PoSt/1123_186463.HtM
5G.okacbd203.asia/PoSt/1123_627868.HtM
5G.okacbd206.asia/PoSt/1123_596041.HtM
5G.okacbd193.asia/PoSt/1123_902533.HtM
5G.okacbd194.asia/PoSt/1123_089856.HtM
5G.okacbd195.asia/PoSt/1123_509951.HtM
5G.okacbd196.asia/PoSt/1123_702905.HtM
5G.okacbd197.asia/PoSt/1123_309793.HtM
5G.okacbd198.asia/PoSt/1123_580362.HtM
5G.okacbd199.asia/PoSt/1123_047549.HtM
5G.okacbd200.asia/PoSt/1123_138863.HtM
5G.okacbd203.asia/PoSt/1123_123547.HtM
5G.okacbd206.asia/PoSt/1123_044981.HtM