C++ 高级观察者模式(相互)替代方案
假设有一个类数据,它不仅包含可以并且将要修改的数据,还包含构建在包含的数据成员上的重要成员函数 进一步假设有一个类HandleData,它获取指向数据实例的指针。HandleData获取数据并计算一些重要的成员编号(已在初始化时)。在初始化和数据更改期间,数字的计算非常重要,因为反复使用函数成员调用计算数字的成本很高(例如执行集成)。 如果数据发生变化,HandleData应通过更新数字来适应变化 到目前为止,问题只是一个观察者模式。现在HandleData还提供了另一个名为TreatHandleData的类,因此数据的更改意味着HandleData的更改,这同样意味着TreatHandleData的更改。在所有情况下,为了减少计算时间,每次数据/处理数据更改时都必须初始化一些数字 如果所有这些类都需要可复制,那么混乱似乎是完全的 我真的很想看到一些我在下面写的东西的替代品。特别是因为在我的例子中,所有类都必须从一个类派生。这似乎不对。 我的简单尝试是:C++ 高级观察者模式(相互)替代方案,c++,observer-pattern,C++,Observer Pattern,假设有一个类数据,它不仅包含可以并且将要修改的数据,还包含构建在包含的数据成员上的重要成员函数 进一步假设有一个类HandleData,它获取指向数据实例的指针。HandleData获取数据并计算一些重要的成员编号(已在初始化时)。在初始化和数据更改期间,数字的计算非常重要,因为反复使用函数成员调用计算数字的成本很高(例如执行集成)。 如果数据发生变化,HandleData应通过更新数字来适应变化 到目前为止,问题只是一个观察者模式。现在HandleData还提供了另一个名为TreatHandl
#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模式