空中社区

首页 » 〓〓娱乐地带〓〓 » ┫数码风云┣ » 编程与项目开发 » C++设计模式--观察者
计算机紧急响应组 - 2008-6-12 10:45:00


观察者模式是应用非常广泛的设计模式之一,前面已经用C#实现了,下面是C++的实现,在C++实现中,C++中没有接口的概念,但是可以用抽象类类代替Java或C#中的接口,在C++中抽象类中从派生类中抽象出来的函数(方法),必须定义成纯虚函数,这样在后面的使用中才可以通过基类的指针来访问这些函数,面向对象的语言中有个特点,多态只能访问两者中共有的部分。
计算机紧急响应组 - 2008-6-12 10:45:00
#include <iostream>
#include <vector>
using namespace std;
class CObserver//观察者基类(虚基类)
{
public:
CObserver(){}
~CObserver(){}
virtual void Update()=0;
virtual void Display()=0;
protected:
private:
};
class CSubject//实体(虚基类)
{
public:
CSubject(){}
~CSubject(){}
virtual void Notify()=0;
virtual void Attach(CObserver *pObj)=0;
virtual void Detach(CObserver *pObj)=0;
protected:
vector<CObserver*> m_vecObj;//用来保存观察
private:
};
class CConcreteSubject : public CSubject//具体的主体
{
public:
CConcreteSubject(int ix,int iy):m_ix(ix),m_iy(iy){}
~CConcreteSubject(){}
void SetData(int ix,int iy)
{
  m_ix=ix;
  m_iy=iy;
  Notify();
}
int GetIx()
{
  return m_ix;
}
int GetIy()
{
  return m_iy;
}
void Notify()//通知所有的观察更新数据
{
  for (vector<CObserver*>::iterator ptr=m_vecObj.begin();ptr<m_vecObj.end();++ptr)
  {
  (*ptr)->Update();
  }
}
void Attach(CObserver *pObj)//添加观察者
{
  m_vecObj.push_back(pObj);
}
void Detach(CObserver *pObj)//删除观察者
{
  vector<CObserver*>::iterator ptr=m_vecObj.begin();
  for (;ptr<m_vecObj.end();++ptr)
  {
  if (*ptr==pObj)
  {
    break;
  }
  }
  m_vecObj.erase(ptr);
}
void DisplaySub()//输出具体实体的数据
{
  cout<<"Subject:"<<m_ix<<"---"<<m_iy<<endl;
}
private:
//具体实休所包含的数据
int m_ix;
int m_iy;
};
class CConcreteObserverA : public CObserver//具体观察者A
{
public:
CConcreteObserverA(CConcreteSubject *pSub)//利用具体的主体初始化观察者
{
  m_ix=pSub->GetIx();
  m_iy=pSub->GetIy();
  m_pSub=pSub;
}
void SetData(int ix,int iy)//改变观察者中的数据
{
  m_pSub->SetData(ix,iy);//实际上是改变具体的主体的数据
}
void Display()
{
  cout<<"CConcreteObserverA:"<<m_ix<<"---"<<m_iy<<endl;
}
void Update()//利用主体的指针改变观察者的数据
{
  m_ix=m_pSub->GetIx();
  m_iy=m_pSub->GetIy();
}
protected:
private:
int m_ix;
int m_iy;
CConcreteSubject *m_pSub;//具体的主体的指针
};
class CConcreteObserverB : public CObserver
{
public:
CConcreteObserverB(CConcreteSubject *pSub)
{
  m_ix=pSub->GetIx();
  m_iy=pSub->GetIy();
  m_pSub=pSub;
}
void SetData(int ix,int iy)
{
  m_pSub->SetData(ix,iy);
}
void Display()
{
  cout<<"CConcreteObserverA:"<<m_ix<<"---"<<m_iy<<endl;
}
void Update()
{
  m_ix=m_pSub->GetIx();
  m_iy=m_pSub->GetIy();
}
protected:
private:
int m_ix;
int m_iy;
CConcreteSubject *m_pSub;
};
int main()
{
CConcreteSubject sub(3,4);//实例化具体的主体
CConcreteObserverA *pObserA=new CConcreteObserverA(&sub);//实例化一个观察者
CConcreteObserverB *pObserB=new CConcreteObserverB(&sub);//实例化一个观察者
sub.Attach(pObserA);//把观察者添加到主体里保存起来
sub.Attach(pObserB);
pObserA->Display();
pObserB->Display();

//当具体的主体改变时,所有的观察者也跟着变
sub.SetData(5,6);
pObserA->Display();
pObserB->Display();
sub.DisplaySub();
//其中任何一个观察者改变,其余的观察者也随机改变,包括主体
pObserA->SetData(7,8);
pObserA->Display();
pObserB->Display();
sub.DisplaySub();
pObserB->SetData(9,10);
pObserA->Display();
pObserB->Display();
sub.DisplaySub();
//删除一个观察者,当具体的主体改变后,被删除的那个观察者没有被改变
sub.Detach(pObserB);
sub.SetData(11,12);
pObserA->Display();
pObserB->Display();
sub.DisplaySub();
system("pause");
return 0;
}
计算机紧急响应组 - 2008-6-12 10:45:00
再放一份以类模板的代码

#include <iostream>
#include <vector>
#include <string>
using namespace std;
class CObserver
{
public:
CObserver(){}
~CObserver(){}
virtual void Update()=0;
protected:
private:
};
class CSubject
{
public:
CSubject(){}
~CSubject()
{
  m_vecObj.clear();
}
virtual void Attach(CObserver *)=0;
virtual void Detach(CObserver *)=0;
virtual void Notify()=0;
protected:
vector<CObserver *> m_vecObj;
private:
};
template<class T>
class CConcreteSubject : public CSubject
{
public:
CConcreteSubject(T x,T y):m_x(x),m_y(y){}
~CConcreteSubject(){}
void SetDate(T x,T y)
{
  m_x=x;
  m_y=y;
  Notify();
}
T GetX()
{
  return m_x;
}
T GetY()
{
  return m_y;
}
void Notify()
{
  for (vector<CObserver *>::iterator ptr=m_vecObj.begin();ptr<m_vecObj.end();++ptr)
  {
  (*ptr)->Update();
  }
}
void Attach(CObserver *pObj)
{
  m_vecObj.push_back(pObj);
}
void Detach(CObserver *pObj)
{
  vector<CObserver *>::iterator ptr=m_vecObj.begin();
  for (;ptr<m_vecObj.end();++ptr)
  {
  if (*ptr==pObj)
  {
    break;
  }
  }
  m_vecObj.erase(ptr);
}
void DisplaySub()
{
  cout<<"ConcreteSubject:"<<m_x<<"--"<<m_y<<endl;
}
protected:
private:
T m_x;
T m_y;
};
template<class T>
class CConcreteObserverA : public CObserver
{
public:
CConcreteObserverA(CConcreteSubject<T> *pObj)
{
  m_x=pObj->GetX();
  m_y=pObj->GetY();
  m_pSub=pObj;
  m_pSub->Attach(this);
}
void SetData(T x,T y)
{
  m_pSub->SetDate(x,y);
}
void Update()
{
  m_x=m_pSub->GetX();
  m_y=m_pSub->GetY();
}
void Display()
{
  cout<<"CConcreteObserverA:"<<m_x<<"---"<<m_y<<endl;
}
protected:
private:
T m_x;
T m_y;
CConcreteSubject<T> *m_pSub;
};

template<class T>
class CConcreteObserverB : public CObserver
{
public:
CConcreteObserverB(CConcreteSubject<T> *pObj)
{
  m_x=pObj->GetX();
  m_y=pObj->GetY();
  m_pSub=pObj;
  m_pSub->Attach(this);
}
void SetData(T x,T y)
{
  m_pSub->SetDate(x,y);
}
void Update()
{
  m_x=m_pSub->GetX();
  m_y=m_pSub->GetY();
}
void Display()
{
  cout<<"CConcreteObserverB:"<<m_x<<"---"<<m_y<<endl;
}
protected:
private:
T m_x;
T m_y;
CConcreteSubject<T> *m_pSub;
};

int main()
{
CConcreteSubject<string> sub("ecjtu","cert");
CConcreteObserverA<string> *pobjA=new CConcreteObserverA<string>(&sub);
CConcreteObserverB<string> *pobjB=new CConcreteObserverB<string>(&sub);
sub.DisplaySub();
pobjA->Display();
pobjB->Display();
sub.SetDate("ECJTU","CERT");
sub.DisplaySub();
pobjA->Display();
pobjB->Display();
pobjA->SetData("ecjtu","cert");
sub.DisplaySub();
pobjA->Display();
pobjB->Display();
system("pause");
return 0;
}
chenmling9 - 2008-6-12 11:32:00
大二上学过C++.到现在已经完全忘光了。知道它是面向对象的,学了以后会有用的,可是我对它就是没有一点兴趣
wshitufu - 2008-6-19 18:26:00
牛逼啊,看不懂
1
查看完整版本: C++设计模式--观察者