通用主题类观察者模式

Generic Subject class Observor Pattern

本文关键字:观察者模式      更新时间:2023-10-16

我一直在给以下问题解决。创建一个泛型Subject类(引用observer Pattern),使其可以接受任何数据类型(原语类型或用户类型)。寄存器、删除和通知函数也需要是可定制的。例如,我们有一个WeatherStation类,它在数据类型为"int"时通知观察器。它在注册和删除观察器时创建一个DB条目。

另一个示例(未显示)是broadcastthandler,它通知观察器股票交易所报价。它在文件中记录注册和删除观察器。

我写了下面的代码来实现它。
#include <iostream>
#include <set>
template <class T>
class Observor
{
  public :
  virtual void update(const T& t) = 0;
  virtual ~Observor(){}
};
template<class T>
class Subject
{
  public :
  virtual void registerObservor(Observor<T>* obv) = 0;
  virtual void removeObservor(Observor<T>* obv) = 0;
  virtual void notifyObservors(T t);
  virtual ~Subject(){}
};
template<class T>
class WeatherStation : public Subject<T>
{
  public :
  void registerObservor(Observor<T>* obv)
  {
    _observors.insert(obv);
    //Make DB Entry
  }
  void removeObservor(Observor<T>* obv)
  {
    if(_observors.find(obv) != _observors.end())
    {
        _observors.erase(obv);
        //Make DB Entry
    }
  }
  void notifyObservors(T t)
  {
    for(auto itr = _observors.begin(),
    itrEnd = _observors.end(); itr != itrEnd; ++itr)
    {
        (*itr)->update(t);
    }
  }
private :
std::set< Observor<T>* > _observors;
};
int main()
{
  WeatherStation<int> wStation;
}

我从链接器

得到以下错误
observor_pattern.o:observor_pattern.cpp:(.rdata$_ZTV7SubjectIiE[__ZTV7SubjectIiE]+0x10)||undefined reference to `Subject<int>::notifyObservors(int)'

确实(正如链接器告诉您的那样)您没有Subject<T>::notifyObservors(T)的定义,并且您没有将其声明为=0。这是故意的吗?我认为合适的代码应该是

template<class T>
class Subject
{
  public :
  virtual void registerObservor(Observor<T>* obv) = 0;
  virtual void removeObservor(Observor<T>* obv) = 0;
  virtual void notifyObservors(T t) = 0;
                               //   ^^^
  virtual ~Subject(){}
};

虽然更好的方法是在Subject中拥有所有的观察器处理代码,而不是在WeatherStation中,因为这似乎是Subject类的全部内容。Subject负责处理Observor s, WeatherStation负责从传感器等获取数据。