设计模式之(十、观察者模式(ObServer)/发布订阅模式(Pblish/Subscribe))

来源:互联网 发布:如何调教一个抖m知乎 编辑:程序博客网 时间:2024/04/28 01:54

设计模式之十、观察者模式(ObServer)/发布订阅模式(Pblish/Subscribe)
适用范围:
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
书中的实例:
通过前台服务员观察公司领导,当领导回来后,通知所有观察者对象,告诉他们停止与工作无关的事,专心工作。

观察者模式结构图如下所示:

 

1、主题接口类ISubject
ISubject.h
Class IObServer;//引用与它耦合的类,否则可能报找不到该类的错误
virtual void Attach(IObServer *o) = 0;
virtual void Detch(IObServer *o) = 0;
virtual void Notify() = 0;
void SetSubject(string subject);
void GetSubject();

protected:
string m_subject;
vector<IObServer*> m_obs;
设置、获取主题信息的方法在cpp中实现即可。

2、观察者接口类IObServer.h
Class ISubject;
virtual void Update() = 0;
protected:
string m_name;
ISubject *m_sub;

3、具体的主题类 CConcreteSubjectA.cpp
CConcreteSubjectA::Attach(IObServer *o)
{
  m_obs.push_back(o);
}
//删除某一观察者对象
//因为使用vector的方式来存储,做删除操作时,比较麻烦,只能循环遍历来进行匹配操作,可以考虑使用map可以直接定位.
CConcreteSubjectA::Detch(IObServer *o)
{
    vector<IObServer*> ::iterator iter;
   for(iter = m_obs.begin(); iter != m_obs.end(); ++iter)

 {
   if(*iter == 0 )
   {
     m_obs.erase(iter);
     return;
   }
 }
}

CConcreteSubjectA::Notify()
{
   vecotr<IObServer*> ::iterator iter;
   IObServer *o;
   for(iter = m_obs.begin(); iter != m_obs.end(); ++iter)
  {
    o = *iter;
    o->Update();
   }
}

4、具体的观察者对象:CConcreteObServerA.cpp
CConcreteObServerA::CConcreteObServerA(string name, ISubject *sub)
{
   m_name = name;
   m_sub = sub;
}

CConcreteObServerA::CConcreteObServerA()
{
}

CConcreteObServerA::Update()
{
   string mess = m_sub->GetSubject();
   mess += m_name;
   mess += ",关闭股票,快点工作!";
   printf("%s/n", mess.c_str());
}

5、客户端程序main.cpp
CConcreteSubjectA *sub = new CConcreteSubjectA();
CConcreteObServerA *a = new CConcreteObServerA("bixy", sub);
CConcreteObServerA *b = new CConcreteObServerA("bixiaoyang", sub);
CConcreteObServerA *c = new CConcreteObServerA("xiaoyang", sub);
sub->Attach(a);
sub->Attach(b);
sub->Attach(c);

sub->Detch(b);

sub->SetSubject("老板回来了!");

sub->Notify();

 

if( sub != NULL)
{
    delete sub;
}

if( a != NULL )
{
    delete a;
}

if( b != NULL )
{
    delete b;
}

if( c != NULL )
{
    delete c;
}

//释放内存

 

以上,仅供参考。

原创粉丝点击