通用观察者模式
generic observer pattern
我正在使用代码,它有很多观察者模式实现。所有这些都以这样的方式组织:
观察者要实现的一些接口:
class ObserverInterface {
virtual void FooOccurs() = 0;
};
一些类,它实现了注册、注销和通知:
class ObservableImpl {
public:
Register(ObserverInterface *observer);
Unregister(ObserverInterface *observer);
private:
void SomeMethod() {
// foo things
for(auto &observer: observers) {
observer.FooOccurs();
}
}
};
每次复制粘贴注册和取消注册以及实现观察者接口的每个方法的通知时。每次程序员必须记住调用 Unregister(( 时,如果它的观察者将被破坏。
我希望将观察者模式包含在两个类模板中。到目前为止,我有这样的东西:http://rextester.com/UZGG86035
但我不确定我是否没有重新发明轮子。有没有更简单的、众所周知的方法可以做到这一点?
在 C++11 中,我建议采用基于令牌的方法。
注册观察者。 观察者只是一个std::function<void(Signature...)>
.
注册函数返回一个令牌,一个std::shared_ptr<void>
。 只要返回的shared_ptr
有效,广播公司将继续向该听众广播。
侦听器现在负责维护该std::shared_ptr
生存期。
在广播公司内部,您拿着一个weak_ptr
并在广播前.lock()
它。 如果我真的不需要取消注册(通常我不需要(,我会懒洋洋地清理我的weak_ptr
列表。 否则,我返回shared_ptr
具有执行注销的删除功能。
或者,您的听众是shared_ptr<std::function<void(Args...)>>
的,并且在内部存储weak_ptr
。
在此模型中,您无法轻松注入取消注册函数。 但是,这确实意味着他们可以使用别名构造函数本身将回调的生存期与自身紧密绑定,假设它们由shared_ptr管理。
根据我的经验,只需让听众保持std::vector<token>
就足够了。 如果他们有更复杂的倾听关系,他们可以做更多的工作,维护密钥等。
混合模型也是可能的。
对于非线程安全的广播,这两者都是可以接受的,并且可以用几十行代码编写。
线程安全广播变得棘手。 通常,我发现您最好为此使用消息传递模式而不是替代方案,因为这会稍微降低推理并发的难度。
这也不能处理您想要随意注册听众的情况,广播公司和听众的生命周期就像爆米花一样。
- 如何设计具有不同类型的通知和观察器的观察者模式?
- 反射 + 函数指针与观察者模式
- 观察者模式不起作用
- 观察者模式:为什么主题应该是抽象的?
- 观察者模式专业化
- 如何在不必绑定到特定类的情况下实现观察者模式
- C++,函数指针与观察者模式
- C++11观察者模式(信号、插槽、事件、更改广播器/侦听器,或任何您想称之为的东西)
- 实施观察者模式C
- C++自己的观察者模式
- 不同可观察量的观察者模式
- 通过Boost信号的观察者模式2
- 具有类型信息的观察者模式(C++)
- 代码设计:观察者模式
- 观察者模式和继承:未调用正确的函数
- C++和Qt:观察者模式错误
- 在C++中实现观察者模式
- 多少听众是太多的观察者模式
- 当观察者希望观察不同的项目时实现观察者模式
- 通用观察者模式