设计模式之十、观察者模式(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;
}
//释放内存
以上,仅供参考。