C++中简单的事件通知: 调用接口
观察者设计模式:
监听者:处理事件
观察者:观察事件,当有事件到来,通知监听者处理事件
假如:
Listener1 感兴趣 1 2 事件
Listener2 感兴趣 2 3 事件
Listener3 感兴趣 1 3 事件
监听者 把自己的标识,还有感兴趣的事件类型 注册到 观察者里
流程:
通过注册把监听者自己的标识,及感兴趣的事件注册到观察者里,当事件到来后,观察者通过注册表里面监听者和它所感兴趣的事件,通过事件类型找到相对应的监听者,通知监听者来处理这些事件。
观察者里:
//保存事件的注册表 一对多的关系 int代表事件 ,vector代表 对这个事件感兴趣的监听者的集合
std::map<int, std::vector<const Listener*>> mymap;
//一个键对应一个集合 将感兴趣的事件和对其感兴趣的监听者 绑定起来 注册到map表里
示意图如下:
代码如下:
#include<iostream>
#include<vector>
#include<string>
#include<map>
class Listener //设置成继承 为了扩展
{
public:
Listener(std::string name) :mname(name) {}
virtual void handleMessage(int message)const = 0; //纯虚函数,抽象接口,处理事件的
protected:
std::string mname; //监听者唯一的标识
};
class Listener1 :public Listener
{
public:
Listener1(std::string name) :Listener(name) {}
virtual void handleMessage(int message)const
{
switch (message)
{
case 1:
std::cout << mname << " has been solved 1 message!" << std::endl; //可以写成回调函数
break;
case 2:
std::cout << mname << " has been solved 2 message!" << std::endl;
break;
default:
std::cout << mname << " no interested this message!" << std::endl;
break;
}
}
};
class Listener2 :public Listener
{
public:
Listener2(std::string name) :Listener(name) {}
virtual void handleMessage(int message)const
{
switch (message)
{
case 2:
std::cout << mname << " has been solved 2 message!" << std::endl;
break;
case 3:
std::cout << mname << " has been solved 3 message!" << std::endl;
break;
default:
std::cout << mname << " no interested this message!" << std::endl;
break;
}
}
};
class Listener3 :public Listener
{
public:
Listener3(std::string name) :Listener(name) {}
virtual void handleMessage(int message)const
{
switch (message)
{
case 1:
std::cout << mname << " has been solved 1 message!" << std::endl;
break;
case 3:
std::cout << mname << " has been solved 3 message!" << std::endl;
break;
default:
std::cout << mname << " no interested this message!" << std::endl;
break;
}
}
};
class Observe //观察者 监听者要注册事件到观察者
{
public:
typedef std::map<int, std::vector<const Listener*>> _Mty;
typedef std::vector<const Listener*> _Vty;
// 注册的接口,通过传入的监听者(哪一个监听者) 和 事件(对哪一个事件感兴趣)
void registerMessage(int message, const Listener* pls)//将事件插入map中
{
_Mty::iterator fit = mymap.find(message); //查找
if (fit != mymap.end())
{
fit->second.push_back(pls);
}
else//新事件,说明没被注册
{
_Vty vec;
vec.push_back(pls);//将监听者插入到集合中
mymap[message] = vec;
}
}
//观察者通知监听者处理事件
//接收事件(通过外部的事件类型传到形参) 通过这个接口接收事件,并通知感兴趣的监听者处理事件
void notify(int message)
{
_Mty::iterator fit = mymap.find(message);
if (fit != mymap.end())
{
_Vty::iterator it = fit->second.begin();
while (it != fit->second.end())
{
(*it)->handleMessage(message); //观察者调用监听者的接口
it++;
}
}
}
private://保存事件的注册表 一对多的关系 int代表事件 ,vector代表 对这个事件感兴趣的监听者的集合
std::map<int, std::vector<const Listener*>> mymap; //放到map容器中
};
int main()
{
Listener1 L1("listener1");
Listener2 L2("listener2");
Listener3 L3("listener3");
Observe ob;
ob.registerMessage(1, &L1);
ob.registerMessage(2, &L1);
ob.registerMessage(2, &L2);
ob.registerMessage(3, &L2);
ob.registerMessage(1, &L3);
ob.registerMessage(3, &L3);
ob.notify(3);
return 0;
}
打印结果: