实现“静态观察者模式”

时间:2013-04-04 09:50:34

标签: c++ observer-pattern

我有一个带有方法模板的类:

struct Subject
{
  template <typename T>
  void doSomething()
  {
    ..
  }
};

现在每当调用doSomething时(任何T)我都希望通知“观察者”:

  template <typename T>
  void onDoSomething()
  {
    ..
  }

观察者是一个方法模板很重要(包含方法的类模板也可以工作)。如果不是,我可以实现常见的观察者模式。

可以修改Subject::doSomething()以便它调用方法。但是,类Subject不应该“知道”具体的Observer / observer方法。

这背后的想法是:我在两个项目中使用Subject。我只需要其中一个观察者(并且有)。

有没有办法实现这个目标?

2 个答案:

答案 0 :(得分:2)

艰难的一个。它似乎归结为

  

通知必须在编译时可解析(它是模板)

并且同时

  

通知不应在编译时解析(Subject不应该知道观察者)

我可以想到两种方法:


1.添加doSomething的重载:

template <typename T, typename Observer>
void doSomething()
{
  doSomething<T>();
  Observer::onDoSomething<T>();
}

然后调用项目A中的单参数版本和项目B中的双参数版本。


2.让定义Subject的文件包含一个标题,每个项目中的标题将不同/不同:

<强> Subject.h

#include "observer_def.hpp"

struct Subject
{
  template <typename T>
  void doSomething()
  {
    ..
    notifyDoSomething<T>();
  }
};

项目A中的observer_def.hpp

template <typename>
inline void notifyDoSomething() {}

项目B中的observer_def.hpp

template <typename T>
inline void notifyDoSomething()
{
  MyObserver::onDoSomething<T>();
}

答案 1 :(得分:1)

我终于通过模板专业化找到了令人满意的解决方案:

///signaling struct. Could be replaced with any other type.
struct SpecializedObserver{};

///unspecialized:
template <typename>
struct Observer
{
    template <typename T>
    static void onDoSomething()
    {
        //default: do nothing.
    }
};

///optional. Specialize in project A or leave aside in project B:
template<>
struct Observer<SpecializedObserver>
{
    template <typename T>
    static void onDoSomething()
    {
        std::cout << "doing something with " << typeid(T).name() << std::endl; 
    }
};

struct Subject
{
    template <typename T>
    void doSomething()
    {
      Observer<SpecializedObserver>::onDoSomething<T>();
      ..
    }
};

如果我不想要观察者,此解决方案不需要任何操作。如果我想要一个,我专门研究Observer模板,如上所示。

编辑:这在我的测试中运行良好,但问题是如何在具有不同编译单元的场景中使用它 - 我应该在哪里定义专业化?