一. 简介
最近遇到了这样一个问题:A类中包含了一个成员类B类,B类会实时更新路由表,更新完之后希望能实时将新的路由表通知给A,使得A能更新总表并进行多项操作。而实际上,作为一个成员类的B类是没有权限去调用A的函数或者通知A的,而使用函数指针又不是优雅的C++解决方案,因此这里采用观察者模式解决。下面给出一个由观察者模式写的简单小例子。
二. 观察者模式示例代码
- 首先我们需要完成底层回调函数类和监听者类
//lsd.h
#pragma once
#include <list>
//监听者
class IListenner
{
public:
virtual void onNotify(int value) = 0;
};
//观察者
class INotifier
{
public:
virtual void registerListenner(IListenner *l) = 0;
virtual void removeListenner(IListenner *l) = 0;
virtual void notify() = 0;
};
// 成员类B
class lsd : public INotifier
{
int m_table;
std::list<IListenner*> listenners;
public:
lsd(IListenner *listener);
~lsd();
void registerListenner(IListenner *l);
void removeListenner(IListenner *l);
void notify();
void __timeWatch();
};
/*-----------------------------------------------------------------------*/
//lsd.cpp
#include "lsd.h"
#include <Windows.h>
#include <iostream>
lsd::lsd(IListenner *listener)
{
m_table = 0;
registerListenner(listener);
__timeWatch();
}
lsd::~lsd()
{
m_table = 0;
}
void lsd::registerListenner(IListenner *l)
{
std::cout << "register listener" << std::endl;
listenners.push_back(l);
}
void lsd::removeListenner(IListenner *l)
{
std::cout << "remove listener" << std::endl;
std::list<IListenner*>::iterator it;
for (it = listenners.begin(); it != listenners.end(); it++)
{
if (*it == l)
{
listenners.remove(l);
break;
}
}
}
void lsd::notify()
{
std::list<IListenner*>::iterator it;
for (it = listenners.begin(); it != listenners.end(); it++)
{
(*it)->onNotify(m_table);
}
}
void lsd::__timeWatch()
{
Start:
time_t start_time = GetTickCount();
time_t now_time = start_time;
while (now_time - start_time <= 1000)
{
now_time = GetTickCount();
}
notify();
goto Start;
}
- 完成主类A
// connection.h
#pragma once
#include "lsd.h"
class PeerConnection : public IListenner
{
lsd *m_lsd;
int m_int;
public :
PeerConnection();
~PeerConnection();
void onNotify(int value);
private:
void __update(int val);
};
/*-----------------------------------------------------------------------*/
//connection.cpp
#include "control.h"
#include <iostream>
PeerConnection::PeerConnection()
{
m_lsd = new lsd(this);
}
PeerConnection::~PeerConnection()
{
delete m_lsd;
}
void PeerConnection::__update(int val)
{
if (!val)
{
m_int++;
std::cout << "callback work, m_int = " << m_int << " second" << std::endl;
}
}
void PeerConnection::onNotify(int value)
{
__update(value);
}
由此,我们实现了一个由lsd和PeerConnection组成的简单例子,其中lsd作为成员类,每隔一秒会触发一次监听者函数,通过设置好的回调函数激活PeerConnection相应的回调函数从而实现我们的目的。