观察者模式(Observer)定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
假设猫大叫一声,所有的老鼠开始逃跑,这时,老鼠是观察者,猫是被观察者,当被观察者状态改变(猫大叫一声)时将发送一个通知给其所有观察者,结构图为:
实现代码:
//Observer.h
class Observer
{
public:
virtual ~Observer();
virtual void Update() = 0;
protected:
Observer();
};
//Observer.cpp
#include "stdafx.h"
#include "Observer.h"
Observer::Observer()
{
}
Observer::~Observer()
{
}
//Mouse.h
#include "Observer.h"
class Mouse : public Observer
{
public:
Mouse(char*);
virtual ~Mouse();
void Update();
private:
char* m_pName;
};
//Mouse.cpp
#include "stdafx.h"
#include "Mouse.h"
#include <iostream>
using namespace std;
Mouse::Mouse(char* pName)
{
this->m_pName = pName;
}
Mouse::~Mouse()
{
}
void Mouse::Update()
{
cout << this->m_pName << "听到猫叫,开始逃跑" << endl;
}
//Subject.h
#include <vector>
class Observer;
class Subject
{
public:
virtual ~Subject();
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual void Notify();
protected:
Subject();
std::vector<Observer*> m_vObservers;
};
//Subject.cpp
#include "stdafx.h"
#include "Subject.h"
#include "Observer.h"
#include <algorithm>
#include <functional>
using namespace std;
Subject::Subject()
{
}
Subject::~Subject()
{
}
void Subject::Attach(Observer* pObs)
{
m_vObservers.push_back(pObs);
}
void Subject::Detach(Observer* pObs)
{
m_vObservers.erase(remove_if(m_vObservers.begin(), m_vObservers.end(), bind1st(equal_to<Observer*>(), pObs)));
}
void Subject::Notify()
{
vector<Observer*>::iterator it = m_vObservers.begin();
for( ; it != m_vObservers.end(); ++it )
{
(*it)->Update();
}
}
//Cat.h
#include "Subject.h"
class Cat : public Subject
{
public:
Cat();
virtual ~Cat();
void Cry();
};
//Cat.cpp
#include "stdafx.h"
#include "Cat.h"
#include <iostream>
using namespace std;
Cat::Cat()
{
}
Cat::~Cat()
{
}
void Cat::Cry()
{
cout << "猫大叫一声" << endl;
this->Notify();
}
//main.cpp
#include "stdafx.h"
#include "Cat.h"
#include "Mouse.h"
int main(int argc, char* argv[])
{
Observer* pMouseA = new Mouse("白鼠");
Observer* pMouseB = new Mouse("黑鼠");
Cat cat;
cat.Attach(pMouseA);
cat.Attach(pMouseB);
cat.Cry();
return 0;
}
运行结果:
猫大叫一声
白鼠听到猫叫,开始逃跑
黑鼠听到猫叫,开始逃跑