// 先看下观察者如何实现 Observer.h
# ifndef OBSEVER_H_1
# define OBSEVER_H_1
class Observer
{
public:
Observer() { ; }
virtual ~Observer() { ; }
// 子类必须实现自己的Update方法
virtual void Update(void* pArg) = 0; // 这是纯虚函数,没有函数体;
// “=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”;
// 纯虚函数只有函数的名字而不具备函数的功能,不能被调用。它只是通知编译系统: “在这里声明一个虚函数,留待派生类中定义”。
// 在派生类中对此函数提供定义后,它才能具备函数的功能,可被调用。
// 这里的 virtual 起到了接口作用
};
# endif
// Observerable.h
#pragma once
class Observer;
#include <string>
#include <list>
using namespace std;
class Observerable
{
public:
Observerable();
virtual ~Observerable();
// 添加一个观察者
void Attach(Observer* pOb);
// 删除指定的观察者
void Detach(Observer* pOb);
// 获取观察者数量
int GetObseverCount() const
{
return _Obs.size();
}
// 删除所有的观察者
void DetachAll()
{
_Obs.clear();
}
virtual void GetSomeNews(string str)
{
SetChange(str);
}
protected:
void SetChange(string news);
private:
void Notify(void* pArg);
private:
bool _bChange;
list<Observer*> _Obs; // 观察者使用一个标准库的List保存
};
// -------end-------end-------end-------end-------end-------end-------end-------end
// 来看一下实现
#include "stdafx.h"
#include "Observerable.h"
Observerable::Observerable():_bChange(false) // 构造函数,设置默认值(据说这种写法更高效)
{
}
Observerable::~Observerable()
{
// 析构函数,do nothing.
}
// 添加一个观察者(指针类型),如果已经存在,直接返回
void Observerable::Attach(Observer* pOb)
{
if (pOb == NULL)
{
return;
}
//
auto it = _Obs.begin();
for (; it != _Obs.end(); it++)
{
if (*it == pOb)
{
return;
}
}
_Obs.push_back(pOb); // 在尾部插入,
}
// 删除一个观察者对象。
void Observerable::Detach(Observer* pOb)
{
if ((pOb == NULL) || (_Obs.empty() == true))
{
return;
}
_Obs.remove(pOb); // 这里的时间复杂度是O(n), 但观察者一般都不多,不需要用更加高级的数据结构
}
void Observerable::SetChange(string news)
{
_bChange = true;
Notify( ( (void*)news.c_str() ));
}
// 通知观察者
void Observerable::Notify(void* pArg)
{
if (_bChange == false)
{
return;
}
// 遍历List,每一个观察者对象都调用 Update通知,把通知的信息pArg传递给观察者
auto it = _Obs.begin(); // 这里使用了auto,有编译器自己推导出遍历类型
for (; it != _Obs.end(); it++)
{
(*it)->Update(pArg);
}
_bChange = false;
}
// 来看下观察者模式要怎么用
class News : public Observerable // 继承Observerable, 即News也是一个可观察的对象
{
public:
virtual void GetSomeNews(string str) // 子类实现GetSomeNews
{
SetChange("News: " + str);
}
};
// 定义User1 为观察者,需要实现 Update 方法
class User1:public Observer
{
public:
virtual void Update(void* pArg) // 子类里的virtual表示要覆盖基类的Update这个虚函数
{
cout << "User1 Got News: " << reinterpret_cast<char*>(pArg) <<endl;
}
};
// 定义其他类型的观察者
class User2 :public Observer
{
public:
virtual void Update(void* pArg)
{
cout << "User2 Got News: " << reinterpret_cast<char*>(pArg) <<endl;
}
};
int main()
{
User1 u1;
User2 u2;
News n1;
n1.GetSomeNews("T0");
cout << n1.GetObseverCount() << endl; // 0
n1.Attach(&u1);
n1.Attach(&u2);
n1.GetSomeNews("T1");
cout << n1.GetObseverCount() << endl; // 2
n1.Detach(&u2);
n1.GetSomeNews("T2");
cout << n1.GetObseverCount() << endl; // 1
n1.DetachAll();
n1.GetSomeNews("T3");
cout << n1.GetObseverCount() << endl; // 0
return 0;
}