您的位置:首页 > 其它

设计模式——观察者监听者模式

2017-07-15 22:47 211 查看
*本篇总结一下基于多线程的线程安全的观察者监听者模式。。。→_→*

在阅读本文之前,需要先了解相关知识。。请戳传送门——智能指针的交叉引用问题及解决方法

#include <iostream>
#include <string>
#include <memory>
#include <map>
#include <vector>
using namespace std;

template <typename T>
bool operator==(const weak_ptr<T> &left, const weak_ptr<T> &right)
{
return left.lock() == right.lock();
}

class Listener
{
public:
Listener(string name) :_name(name) {}
virtual void handleMessage(int msgid) = 0;
string _name;
};

class Listener1 : public Listener
{
public:
Listener1(string name) :Listener(name) {}
void handleMessage(int msgid)
{
cout << _name << " ";
switch (msgid)
{
case 0:
cout << " recv 0 msg!" << endl;
break;
case 1:
cout << " recv 1 msg!" << endl;
break;
case 2:
cout << " recv 2 msg!" << endl;
break;
}
}
};

class Listener2 : public Listener
{
public:
Listener2(string name) :Listener(name) {}
void handleMessage(int msgid)
{
cout << _name << " ";
switch (msgid)
{
case 0:
cout << " recv 0 msg!" << endl;
break;
case 2:
cout << " recv 2 msg!" << endl;
break;
}
}
};

class Listener3 : public Listener
{
public:
Listener3(string name) :Listener(name) {}
void handleMessage(int msgid)
{
cout << _name << " ";
switch (msgid)
{
case 1:
cout << " recv 1 msg!" << endl;
break;
case 2:
cout << " recv 2 msg!" << endl;
break;
}
}
};

class Observer
{
public:
void registerListener(weak_ptr<Listener> lp, int msgid)
{
map<int, vector<weak_ptr<Listener>>>::iterator it = _ObserMap.find(msgid);
if (it == _ObserMap.end())
{
vector<weak_ptr<Listener>> vec;
vec.push_back(lp);
_ObserMap.insert(make_pair(msgid, vec));
}
else
{
it->second.push_back(lp);
}
}

void deleteListener(weak_ptr<Listener> lp, int msgid)
{
map<int, vector<weak_ptr<Listener>>>::iterator it = _ObserMap.find(msgid);
if (it != _ObserMap.end())
{
vector<weak_ptr<Listener>>::iterator vecIt = find(it->second.begin(), it->second.end(), lp);
if (vecIt != it->second.end())
it->second.erase(vecIt);
}
}

void dispatchMessage(int msgid)
{
map<int, vector<weak_ptr<Listener>>>::iterator it = _ObserMap.find(msgid);
if (it != _ObserMap.end())
{
vector<weak_ptr<Listener>>::iterator vecIt = it->second.begin();
for (; vecIt != it->second.end(); ++vecIt)
{
shared_ptr<Listener> lp = (*vecIt).lock();
if (lp != NULL)
lp->handleMessage(msgid);
}
}
}
private:
map<int, vector<weak_ptr<Listener>>> _ObserMap;
};

int main()
{
shared_ptr<Listener> p1(new Listener1("Listener1"));
shared_ptr<Listener> p2(new Listener1("Listener2"));
shared_ptr<Listener> p3(new Listener1("Listener3"));

Observer obser;
obser.registerListener(p1, 0);
obser.registerListener(p1, 1);
obser.registerListener(p1, 2);
obser.registerListener(p2, 0);
obser.registerListener(p2, 2);
obser.registerListener(p3, 1);
obser.registerListener(p3, 2);

//obser.deleteListener(p1, 2);

while (true)
{
int msgid;
cout << "msgid:";
cin >> msgid;
obser.dispatchMessage(msgid);
}
return 0;
}


写代码时候的坑:代码坑
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息