观察者模式
观察者模式(Observer Pattern)
观察者模式是行为性设计模式的一种。
定义:定义对象间的一种一对多关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
个人理解:当一个对象发生变化的时候,其他关心该对象的对象能够得到通知并更新自己的状态。
类图中用的UML术语:
泛化:概括描述具体类之间的关系,适用于继承(如下图的Subject与ConcreteSubject)
实现:抽象说明和具体实现之间的关系(如下图的Observer与ConcreteObserver)
聚合:类与类之间整体与部分的关系(如下图的Subject与Observer)
Subject 是目标对象,也就是被观察者
作用:定义被观察者必须实现的职责,能够动态地增加(注册)、删除(取消)观察者;一般是抽象类或者实现类,仅仅作为被观察者必须实现的职责:管理观察者并通知观察者。
Observer 观察者
作用:观察者接收到消息后,即进行update(更新)操作,对接收到的信息进行处理;主要由抽象类或接口来实现。
ConcreteSubject 具体的被观察者
作用:具体的目标对象,用来维护目标状态,当目标对象的状态发生改变时,通知所有注册的有效观察者,让观察者执行相应的处理。
ConcreteObserver 具体的观察者
作用:每个观察者接收到消息后处理反应不同,各个观察者都有自己的处理方法。
代码如下:
#include "stdafx.h"
#include <list>
#include <algorithm>
#include <iostream>
class Subject;
//观察者
class Observer
{
public:
virtual void update(Subject *subject) = 0;
};
//被观察者
class Subject
{
public:
virtual void attach(Observer *o) //添加一个观察者
{
this->m_listObsever.push_back(o);
}
virtual void detach(Observer* po) //删除一个观察者
{
std::list<Observer *>::iterator iter = find(m_listObsever.begin(), m_listObsever.end(),po);
if (m_listObsever.end() != iter)
{
m_listObsever.erase(iter);
}
}
virtual void notifyObserver() //通知所有注册的观察者
{
for (std::list<Observer *>::iterator iter = m_listObsever.begin();iter != m_listObsever.end();++iter)
{
(*iter)->update(this);
}
}
virtual void SetStatus(int n) = 0;
virtual int GetStatus() = 0;
private:
std::list<Observer *> m_listObsever; //用list容器存放具体的观察者
};
//具体被观察者
class ConcreteSubject : public Subject
{
public:
void SetStatus(int n) //设置具体被观察者的状态
{
m_Status = n;
}
int GetStatus() //得到具体被观察者的状态
{
return m_Status;
}
private:
int m_Status; //具体被观察者的状态
};
//具体观察者
class ConcreteObserver : public Observer
{
public:
void update(Subject *pSubject) //具体观察者更新
{
printf("the status is : %d\n", pSubject->GetStatus());
}
};
int _tmain(int argc, _TCHAR* argv[])
{
//创建一个被观察者
Subject *p = new ConcreteSubject();
//定义2个观察者
Observer *poA = new ConcreteObserver;
Observer *poB = new ConcreteObserver;
p->SetStatus(100);
p->attach(poA);
p->attach(poB);
p->notifyObserver();
p->SetStatus(60);
p->notifyObserver();
p->SetStatus(30);
p->detach(poA);
p->notifyObserver();
system("pause");
return 0;
}
运行结果: