观察者模式(Observer):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
实现过程:
1.观察者(Observer)将自己注册到被观察对象(Observer)中,被观察对象将观察者存放在一个列表(List)中。
2.被观察对象(Subject)发生了某种变化时,自动从容器中遍历所有注册过的观察者,将变化通知依次所有注册的观察者。
3.观察者(Observer)告诉被观察者(Observer)要撤销观察,被观察者从列表中将观察者去除。
一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。被观察着发出通知时,不需要知道谁是它的观察者。观察者和被观察者用松耦合的方式结合,被观察者不知道观察者的细节,只要这个观察者也是相同的接口实现即可。
UML类图:
观察者模式基本代码如下:
/********************************************************************
filename: Observer.h
created: 2012-09-25
author: firehood
purpose: firehood 学设计模式之---观察者模式
*********************************************************************/
#pragma once
#include "windows.h"
#include <assert.h>
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
// 抽象观察者
class Observer
{
public:
Observer(void){}
virtual ~Observer(void){}
virtual void Update() = 0;
};
// 抽象被观察者
class Subject
{
public:
Subject(void){m_ObserverList.clear();}
virtual ~Subject(void){}
virtual BOOL Attach(Observer *pObserver)
{
if(pObserver == NULL)
{
return FALSE;
}
if(std::find(m_ObserverList.begin(),m_ObserverList.end(),pObserver) != m_ObserverList.end())
{
return FALSE;
}
m_ObserverList.push_back(pObserver);
return TRUE;
}
virtual BOOL Detach(Observer *pObserver)
{
if(pObserver == NULL)
{
return FALSE;
}
m_ObserverList.remove(pObserver);
return TRUE;
}
virtual void Notify(void)
{
list<Observer*>::iterator iter;
for(iter = m_ObserverList.begin();iter != m_ObserverList.end(); iter++)
{
(*iter)->Update();
}
}
private:
list<Observer*> m_ObserverList;
};
typedef string STATE;
// 具体被观察者
class ConcreteSubject: public Subject
{
public:
ConcreteSubject(){};
virtual ~ConcreteSubject(){};
BOOL SetState(STATE SubjectState)
{
if(m_SubjectState != SubjectState)
{
m_SubjectState = SubjectState;
}
cout<<"设置被观察者状态:"<<m_SubjectState<<endl;
return TRUE;
}
STATE GetState()
{
return m_SubjectState;
}
private:
STATE m_SubjectState;
};
// 具体观察着
class ConcreteObserver: public Observer
{
public:
// 构造时需指定具体的被观察者
ConcreteObserver(ConcreteSubject *pSubject):m_pSubject(NULL)
{
assert(pSubject);
m_pSubject = pSubject;
};
virtual ~ConcreteObserver(){}
virtual void Update()
{
m_ObserverState = m_pSubject->GetState();
cout<<"观察者"<<this<<":被观察者状态改变:"<<m_ObserverState<<endl;
}
private:
ConcreteSubject* m_pSubject;
STATE m_ObserverState;
};
客户端调用代码如下:
#include "Observer.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
cout<<"*************************************"<<endl;
cout<<"firehood 学设计模式之---观察者模式"<<endl;
cout<<"*************************************"<<endl;
// 声明被观察者
ConcreteSubject Subject;
// 创建观察者A,观察的对象为Subject
ConcreteObserver *pObserverA = new ConcreteObserver(&Subject);
Subject.Attach(pObserverA);
// 创建观察者B,观察的对象为Subject
ConcreteObserver *pObserverB = new ConcreteObserver(&Subject);
Subject.Attach(pObserverB);
Subject.SetState("状态1");
Subject.Notify();
Subject.SetState("状态2");
Subject.Notify();
delete pObserverA;
delete pObserverB;
system("pause");
return 0;
}
运行结果:
*************************************
firehood 学设计模式之---观察者模式
*************************************
设置被观察者状态:状态1
观察者003A6530:被观察者状态改变:状态1
观察者003A65E0:被观察者状态改变:状态1
设置被观察者状态:状态2
观察者003A6530:被观察者状态改变:状态2
观察者003A65E0:被观察者状态改变:状态2
请按任意键继续. . .