实现"static observer pattern"

Implement a "static observer pattern"

本文关键字:pattern observer static 实现      更新时间:2023-10-16

我有一个类的方法模板:

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

现在每当doSomething被调用时(与任何T一起),我希望有一个"观察者"被通知:

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

观察器必须是一个方法模板(包含方法的类模板也可以)。如果不是,我可以直接实现常见的观察者模式。

修改Subject::doSomething()使其调用一个方法是可以的。但是,Subject类不应该"知道"具体的Observer/Observer方法。

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

有办法做到这一点吗?

很难。这似乎可以归结为

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

,同时

通知不应该在编译时解析(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>();
  }
};
在项目

observer_def.hpp :

template <typename>
inline void notifyDoSomething() {}

observer_def.hpp项目B :

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

我最终通过模板特化找到了一个令人满意的解决方案:

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

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

EDIT:这在我的测试中工作得很好,但是问题是我如何在具有不同编译单元的场景中使用它-我应该在哪里定义专门化?