C++ 高级观察者模式(相互)替代方案

C++ 高级观察者模式(相互)替代方案,c++,observer-pattern,C++,Observer Pattern,假设有一个类数据,它不仅包含可以并且将要修改的数据,还包含构建在包含的数据成员上的重要成员函数 进一步假设有一个类HandleData,它获取指向数据实例的指针。HandleData获取数据并计算一些重要的成员编号(已在初始化时)。在初始化和数据更改期间,数字的计算非常重要,因为反复使用函数成员调用计算数字的成本很高(例如执行集成)。 如果数据发生变化,HandleData应通过更新数字来适应变化 到目前为止,问题只是一个观察者模式。现在HandleData还提供了另一个名为TreatHandl

假设有一个类数据,它不仅包含可以并且将要修改的数据,还包含构建在包含的数据成员上的重要成员函数

进一步假设有一个类HandleData,它获取指向数据实例的指针。HandleData获取数据并计算一些重要的成员编号(已在初始化时)。在初始化和数据更改期间,数字的计算非常重要,因为反复使用函数成员调用计算数字的成本很高(例如执行集成)。 如果数据发生变化,HandleData应通过更新数字来适应变化

到目前为止,问题只是一个观察者模式。现在HandleData还提供了另一个名为TreatHandleData的类,因此数据的更改意味着HandleData的更改,这同样意味着TreatHandleData的更改。在所有情况下,为了减少计算时间,每次数据/处理数据更改时都必须初始化一些数字

如果所有这些类都需要可复制,那么混乱似乎是完全的

我真的很想看到一些我在下面写的东西的替代品。特别是因为在我的例子中,所有类都必须从一个类派生。这似乎不对。

我的简单尝试是:

#include <algorithm> // remove
#include <memory>    // shared_ptr
#include <assert.h>
#include <iostream>  // cout, cerr, endl
#include <vector>

class MutualObserver
{
public:

  MutualObserver() {}

  // copy ctor resets the list of observers
  MutualObserver(const MutualObserver & src) : observer(0) {}

  virtual ~MutualObserver() {};

  // assign op. must be empty to not have a list of observers that persists
  MutualObserver& operator = ( const MutualObserver &rhs ) { return *this; }

  // adds observer
  void add ( MutualObserver * o )
  {
    bool good = true;
    for ( uint i = 0; i<observer.size(); i++)
      if ( observer[i] == o ) good = false;

      if ( good && (o != NULL) ) observer.push_back(o);
  }

  // removes observer
  void remove ( MutualObserver * o )
  {
    if ( o == NULL )
      std::cout<<" in Data::remove - observer is NULL "<<std::endl;

    bool good = true;
    for ( uint i = 0; i<observer.size(); i++)
      if ( observer[i] == o ) good = false;

    if (good && o!=NULL )
      observer.erase
        ( std::remove( observer.begin(), observer.end(), o),observer.end() );
  }

  /// updates obserer o
  void update_observer ( MutualObserver * o )
  {
    for ( uint i = 0; i<observer.size(); i++ )
      if  ( observer[i] == o ) observer[i]->update_yourself();
  }

  /// updates all observers
  void update_all_observers ()
  {
    for (uint i = 0; i<observer.size(); i++)
    {
      observer[i]->update_yourself();
    }
  }

  /// updates all important members esp. of derived classes
  /// observer method, should be implemented for all observers
  virtual void update_yourself () {}

protected:
  std::vector<MutualObserver*> observer;

};


class Data : public MutualObserver
{
public:
  Data () : A(42.) {}
  void setA ( double x ) { A = x; update_all_observers(); }
  double getA () { return A; }
  double multiply ( double x ) { return A * x; } 

private:
  double A;  
};


class HandleData : public MutualObserver
{
  double important_variable;
  std::shared_ptr<Data> mySource;

public:
  HandleData ( std::shared_ptr<Data> source ) 
    :  mySource(source), important_variable(0.)
  {
    assert( source != NULL );
    mySource->add(this); 
    update_yourself();
  }

  HandleData ( const HandleData &src ) 
    :  MutualObserver(src), mySource( src.mySource ),
       important_variable( src.important_variable )
  {
    assert( mySource != NULL );
    mySource->add(this); 
    update_yourself();
  }

  virtual ~HandleData() { if ( mySource!=NULL ) mySource->remove(this); }

  virtual void update_yourself ()
  {
    double A = mySource->getA();
    important_variable = A *2.*3.14;
  }

  double getVariable() const { return important_variable; }
};


class TreatHandleData : public MutualObserver
{
  double important_variable;
  std::shared_ptr<HandleData> mySource;

public:
  TreatHandleData ( std::shared_ptr<HandleData> source ) 
    :  mySource(source), important_variable(0.)
  {
    assert( source != NULL );
    mySource->add(this); 
    update_yourself();
  }

  TreatHandleData ( const TreatHandleData &src ) 
    :  MutualObserver(src), mySource( src.mySource ), 
       important_variable( src.important_variable )
  {
    assert( mySource != NULL );
    mySource->add(this); 
    update_yourself();
  }

  virtual ~TreatHandleData() { if ( mySource!=NULL ) mySource->remove(this); }

  virtual void update_yourself ()
  {
    double A = mySource->getVariable();
    important_variable = A * 365.;
  }

  double getVariable() const { return important_variable; }
};

int main()
{
  std::shared_ptr<Data> observable ( new Data() );
  std::shared_ptr<HandleData> observer ( new HandleData(observable) );
  std::shared_ptr<TreatHandleData> myTHD ( new TreatHandleData(observer) );

  // copy
  std::shared_ptr<Data> observable2 ( new Data( *observable ) );
  std::shared_ptr<HandleData> observer2 ( new HandleData(*observer) );
  std::shared_ptr<TreatHandleData> myTHD2 ( new TreatHandleData(*myTHD) );

  std::cout << "initial Data:            "<< observable->getA() << std::endl;
  std::cout << "initial HandleData:      "<< observer->getVariable() << std::endl;
  std::cout << "initial TreatHandleData: "<< myTHD->getVariable() << std::endl;

  std::cout << " COPY: " << std::endl;

  std::cout << "initial Data:            "<< observable2->getA() << std::endl;
  std::cout << "initial HandleData:      "<< observer2->getVariable() << std::endl;
  std::cout << "initial TreatHandleData: "<< myTHD2->getVariable() << std::endl;

  double a = 99.31232;
  std::cout << " Changing A to " << a << std::endl;
  observable->setA( a );  
  std::cout << " (diff) changed Data:            "<< observable->getA() << std::endl;
  std::cout << " (diff) changed HandleData:      "<< observer->getVariable() << std::endl;
  std::cout << " (diff) changed TreatHandleData: "<< myTHD->getVariable() << std::endl;

  std::cout << " COPY: " << std::endl;

  std::cout << " (same) changed Data:            "<< observable2->getA() << std::endl;
  std::cout << " (diff) changed HandleData:      "<< observer2->getVariable() << std::endl;
  std::cout << " (same) changed TreatHandleData: "<< myTHD2->getVariable() << std::endl;

  return 0;
}
#包括//删除
#包括//shared\u ptr
#包括
#包括//cout、cerr、endl
#包括
类MutualObserver
{
公众:
MutualObserver(){}
//复制ctor重置观察者列表
MutualObserver(const MutualObserver&src):观察者(0){}
virtual~MutualObserver(){};
//assign op.必须为空,才能没有持续存在的观察者列表
MutualObserver&operator=(const MutualObserver&rhs){return*this;}
//添加观察者
void add(MutualObserver*o)
{
好=真;
对于(uint i=0;iadd(本);
更新你自己();
}
virtual~TreatHandleData(){if(mySource!=NULL)mySource->remove(this);}
虚拟无效更新\u您自己()
{
双A=mySource->getVariable();
重要变量=A*365。;
}
double getVariable()常量{返回重要的_变量;}
};
int main()
{
std::共享的ptr可观察(新数据());
std::共享ptr观察者(新处理数据(可观察));
std::共享(新治疗数据(观察者));
//抄袭
std::共享的ptr可观测2(新数据(*可观测));
std::shared_ptr observer 2(新HandleData(*observer));
std::共享的ptr myTHD2(新治疗数据(*myTHD));

std::cout据我所知,您不希望在每次getter调用时重新计算HandleData和TreeHandleData上的数据,因为计算是扩展性的

为什么不使用延迟更新方法呢?getter检查底层数据是否已更改,并仅在这种情况下重新计算。这样,您根本不需要使用observer模式