1. 意图
观察者模式是一种对象行为模式。它定义对象间的一种一对多的的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
2. 别名
依赖(Dependents)、发布-订阅(Publish-Subscribe)
3. 使用场景
1、当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2、当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要被改变。
3、当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,不希望这些对象是紧密耦合的。
4. 角色
4.1、抽象主题(Subject):
它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
4.2、具体主题(Concrete Subject):
将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
4.3、抽象观察者(Observer):
为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
4.4、具体观察者(Concrete Observer):
实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
5. 优缺点
观察者模式的主要的作用就是对对象解耦,将观察者和被观察者完全隔离。
1、观察者模式的优点
观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。
2、观察者模式的缺点
在应用观察者模式时需要考虑一下开发小路问题,程序中包括一个被观察者和多个被观察者,开发和调试比较复杂,而且Java中的消息的通知默认是顺序执行的,一个观察者的卡顿会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。
6. 结构
7. 例子
/*抽象观察者*/
class Observer
{
public:
virtual void Update(int) = 0;
};
/*抽象目标*/
class Subject
{
public:
virtual void Attach(Observer *) = 0; //附加观察者
virtual void Detach(Observer *) = 0; //移除观察者
virtual void Notify() = 0; //通知观察者
};
/*具体观察者*/
class ConcreteObserver : public Observer
{
public:
ConcreteObserver(Subject *pSubject) : m_pSubject(pSubject){}
void Update(int value)
{
cout << "ConcreteObserver get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
/*具体观察者2*/
class ConcreteObserver2 : public Observer
{
public:
ConcreteObserver2(Subject *pSubject) : m_pSubject(pSubject){}
void Update(int value)
{
cout << "ConcreteObserver2 get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
/*具体目标*/
class ConcreteSubject : public Subject
{
public:
void Attach(Observer *pObserver);
void Detach(Observer *pObserver);
void Notify();
void SetState(int state)
{
m_iState = state;
}
private:
std::list<Observer *> m_ObserverList;//观察者列表
int m_iState;
};
//附加观察者
void ConcreteSubject::Attach(Observer *pObserver)
{
m_ObserverList.push_back(pObserver);
}
//移除观察者
void ConcreteSubject::Detach(Observer *pObserver)
{
m_ObserverList.remove(pObserver);
}
//通知观察者
void ConcreteSubject::Notify()
{
std::list<Observer *>::iterator it = m_ObserverList.begin();
while (it != m_ObserverList.end())
{
(*it)->Update(m_iState);
++it;
}
}
int main()
{
// Create Subject 目标实例化
ConcreteSubject *pSubject = new ConcreteSubject();
// Create Observer 创建观察者
Observer *pObserver = new ConcreteObserver(pSubject);
Observer *pObserver2 = new ConcreteObserver2(pSubject);
// Change the state
pSubject->SetState(2);
// Register the observer
pSubject->Attach(pObserver);
pSubject->Attach(pObserver2);
pSubject->Notify();
// Unregister the observer
pSubject->Detach(pObserver);
pSubject->SetState(3);
pSubject->Notify();
delete pObserver;
delete pObserver2;
delete pSubject;
}