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

来源:互联网 发布:sql语句中case when 编辑:程序博客网 时间:2024/05/16 14:10

*本篇总结一下基于多线程的线程安全的观察者监听者模式。。。→_→*

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

#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;}

写代码时候的坑:代码坑