其他分享
首页 > 其他分享> > c – 通用观察者模式

c – 通用观察者模式

作者:互联网

我正在使用代码,它有很多观察者模式实现.所有这些都以这样的方式组织:

一些接口由观察者实现:

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();
      }
    }
};

每次有注册和取消注册的复制粘贴以及ObserverInterface的每个方法的通知实现.每当程序员必须记住调用Unregister()时,如果它的观察者将被破坏.

我希望将观察者模式包含在两个类模板中.到目前为止,我有类似的东西:
http://rextester.com/UZGG86035

但我不确定我是不是要重新发明轮子.是否有更容易,众所周知的方法来做到这一点?

解决方法:

在C 11中,我建议采用基于令牌的方法.

你注册了一个观察者.观察者只是一个std :: function< void(Signature ...)>.

注册函数返回一个标记,即std :: shared_ptr< void>.只要返回的shared_ptr有效,广播公司将继续向该侦听器广播.

监听器现在负责维护std :: shared_ptr生命周期.

在广播公司内部,你在广播前持有一个weak_ptr和.lock().如果我真的不需要取消注册(通常我没有),我懒得清理我的weak_ptrs列表.否则,我返回的shared_ptr有一个删除功能,可以取消注册.

或者,您的侦听器是shared_ptr< std :: function< void(Args ...)>>,并且在内部将weak_ptr存储到同一个.

在此模型中,您无法轻松注入unregistraiton函数.但是,它确实意味着它们可以使用别名构造函数本身将回调的生命周期紧密绑定到它们自己,假设它们由shared_ptr管理.

根据我的经验,只需让听众维护一个std :: vector< token>足够了.如果他们有更复杂的倾听关系,他们可以做更多的工作,维护键等.

混合模型也是可能的.

这两种方法都适用于非线程安全的广播,并且可以用几十行代码编写.

线程安全广播变得棘手.通常我发现你最好使用消息传递模式而不是替代方案,因为这会减少稍微推理并发性的难度.

这也不涉及你想要无限注册听众的情况,而广播和听众的生命就像爆米花.

标签:c,c11,observer-pattern
来源: https://codeday.me/bug/20190824/1706235.html