定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
2. 动机
将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。
O b s e r v e r模式描述了如何建立这种关系。这一模式中的关键对象是目标( s u b j e c t )和观察者( o b s e r v e r )。一个目标可以有任意数目的依赖它的观察者。一旦目标的状态发生改变, 所有的观察者都得到通知。作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步。
这种交互也称为发布-订阅(p u b l i s h - s u b s c r i b e)。目标是通知的发布者。它发出通知时并不需知道谁是它的观察者。可以有任意数目的观察者订阅并接收通知。
3. 适用性
在以下任一情况下可以使用观察者模式:
• 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对
象中以使它们可以各自独立地改变和复用。
• 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
• 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些
对象是紧密耦合的。
4.结构
• S u b j e c t(目标)
— 目标知道它的观察者。可以有任意多个观察者观察同一个目标。
— 提供注册和删除观察者对象的接口。
• O b s e r v e r(观察者)
— 为那些在目标发生改变时需获得通知的对象定义一个更新接口。
• C o n c r e t e S u b j e c t(具体目标)
— 将有关状态存入各C o n c r e t e O b s e r v e r对象。
— 当它的状态发生改变时, 向它的各个观察者发出通知。
• C o n c r e t e O b s e r v e r(具体观察者)
— 维护一个指向C o n c r e t e S u b j e c t对象的引用。
— 存储有关状态,这些状态应与目标的状态保持一致。
— 实现O b s e r v e r的更新接口以使自身状态与目标的状态保持一致。
5.举例
#ifndef OBSERVER_H
#define OBSERVER_H
#include <iostream>
#include <list>
using std::cout;
using std::endl;
using std::list;
class CObserver{
public:
virtual void Update(int)=0;
};
class CSubject{
public:
virtual void Attach(CObserver*)=0;
virtual void Detach(CObserver*)=0;
virtual void Notify()=0;
};
class CObserverFirst : public CObserver{
private:
CSubject* pSubject;
public:
CObserverFirst(CSubject* pTmp) : pSubject(pTmp){}
virtual void Update(int value){
cout<<"CObserverFirst update the value: "<<value<<endl;
}
};
class CObserverSecond : public CObserver{
private:
CSubject* pSubject;
public:
CObserverSecond(CSubject* pTmp) : pSubject(pTmp){}
virtual void Update(int value){
cout<<"CObserverSecond update the value: "<<value<<endl;
}
};
class CConcreateSubject: public CSubject{
private:
int iState;
list<CObserver* > lObserverList;
public:
virtual void Attach(CObserver* pObserver){
lObserverList.push_back(pObserver);
}
virtual void Detach(CObserver* pObserver){
lObserverList.remove(pObserver);
}
virtual void Notify(){
for(list<CObserver* >::iterator it=lObserverList.begin();it!=lObserverList.end();it++){
(*it)->Update(iState);
}
}
void SetState(int iValue){
iState=iValue;
}
};
#endif
#include "observer.h"
int main(){
CConcreateSubject* pSubject=new CConcreateSubject;
CObserver* pObserverA=new CObserverFirst(pSubject);
CObserver* pObserverB=new CObserverSecond(pSubject);
pSubject->SetState(100);
pSubject->Attach(pObserverA);
pSubject->Attach(pObserverB);
pSubject->Notify();
pSubject->Detach(pObserverA);
pSubject->SetState(200);
pSubject->Notify();
delete pSubject;
delete pObserverA;
delete pObserverB;
return 0;
}