C++釋出訂閱者模式demo
阿新 • • 發佈:2019-02-13
#ifndef _OBSERVER_H_ #define _OBSERVER_H_ #include <map> #include <mutex> using namespace std; class Msg { public: virtual int GetMsgID() = 0; virtual void* GetMsg() = 0; }; class MsgContainer; class Subscriber { public: virtual void subscribe(MsgContainer *pMsgContainer, int MsgID); virtual void unsubscribe(MsgContainer *pMsgContainer, int MsgID); virtual void handleMsg(Msg *msg) = 0; }; class MsgContainer { public: virtual void add_subscriber(Subscriber *pSubscriber, int MsgID); virtual void remove_subscriber(Subscriber *pSubscriber, int MsgID); virtual void receiveMsg(Msg *msg); protected: virtual void notify(Msg *msg); private: multimap<int, Subscriber*> m_subscriber; mutex m_mutex; }; class Publisher { public: virtual void sendMsg(MsgContainer *pMsgContainer, Msg *msg); }; class MsgImp :public Msg { public: MsgImp(int MsgID, void *Msgfield); virtual ~MsgImp(); virtual int GetMsgID(); virtual void* GetMsg(); private: int m_MsgID; void *m_Msgfield; }; class SubscriberImp :public Subscriber { public: SubscriberImp(); virtual ~SubscriberImp(); virtual void handleMsg(Msg *msg); private: void *m_expext_field; }; class SubscriberImp2 :public Subscriber { public: SubscriberImp2(); virtual ~SubscriberImp2(); virtual void handleMsg(Msg *msg); private: void *m_expext_field; }; class PublisherImp :public Publisher { public: PublisherImp(); virtual ~PublisherImp(); }; #endif
#include "observer.hpp" #include <iostream> using namespace std; MsgImp::MsgImp(int MsgID, void *Msgfield) { m_MsgID = MsgID; m_Msgfield = Msgfield; } MsgImp::~MsgImp() { } int MsgImp::GetMsgID() { return m_MsgID; } void * MsgImp::GetMsg() { return m_Msgfield; } void Subscriber::subscribe(MsgContainer *pMsgContainer, int MsgID) { pMsgContainer->add_subscriber(this, MsgID); } void Subscriber::unsubscribe(MsgContainer *pMsgContainer, int MsgID) { pMsgContainer->remove_subscriber(this, MsgID); } SubscriberImp::SubscriberImp() { }; SubscriberImp::~SubscriberImp() { delete m_expext_field; }; void SubscriberImp::handleMsg(Msg *msg) { m_expext_field = msg->GetMsg(); cout << __func__ << ": this is the SubscriberImp1..." << endl; cout <<__func__ << ": the MsgID is " << msg->GetMsgID() << endl; cout <<__func__ << ": " << (char *) msg->GetMsg() << ", SubscriberImp1 handle the msg"<<endl; } SubscriberImp2::SubscriberImp2() { }; SubscriberImp2::~SubscriberImp2() { delete m_expext_field; }; void SubscriberImp2::handleMsg(Msg *msg) { m_expext_field = msg->GetMsg(); cout << __func__ << ": this is the SubscriberImp2..." << endl; cout <<__func__ << ": the MsgID is " << msg->GetMsgID() << endl; cout <<__func__ << ": " << (char *) msg->GetMsg() << ", SubscriberImp2 handle the msg"<<endl; } void MsgContainer::add_subscriber(Subscriber *pSubscriber, int MsgID) { lock_guard<mutex> guard(m_mutex); if (m_subscriber.empty()) { m_subscriber.insert(make_pair(MsgID, pSubscriber)); } bool isExist = false; map<int, Subscriber*>::iterator it = m_subscriber.lower_bound(MsgID); while (it != m_subscriber.upper_bound(MsgID)) { if (it->second == pSubscriber) isExist = true; it++; } if (!isExist) { m_subscriber.insert(make_pair(MsgID, pSubscriber)); } } void MsgContainer::remove_subscriber(Subscriber *pSubscriber, int MsgID) { lock_guard<mutex> guard(m_mutex); if (m_subscriber.empty()) { return; } multimap<int, Subscriber*>::iterator it = m_subscriber.lower_bound(MsgID); while (it != m_subscriber.upper_bound(MsgID)) { if (it->second == pSubscriber) { m_subscriber.erase(it); break; } it++; } } void MsgContainer::notify(Msg *msg) { multimap<int, Subscriber*>::iterator it = m_subscriber.lower_bound(msg->GetMsgID()); for (; it != m_subscriber.upper_bound(msg->GetMsgID()); it++) { it->second->handleMsg(msg); } } void MsgContainer::receiveMsg(Msg *msg) { lock_guard<mutex> guard(m_mutex); this->notify(msg); } void Publisher::sendMsg(MsgContainer *pMsgContainer, Msg *msg) { pMsgContainer->receiveMsg(msg); } PublisherImp::PublisherImp(){}; PublisherImp::~PublisherImp(){};
#include "observer.hpp" #include <iostream> using namespace std; int main() { Subscriber *subscriber = NULL; MsgContainer *msgcontainer = new MsgContainer(); Msg *msg = NULL; Publisher *publisher = NULL; char *msgfield = NULL; subscriber = new SubscriberImp(); subscriber->subscribe(msgcontainer, 2); Subscriber *subscriber2 = NULL; subscriber2 = new SubscriberImp2(); subscriber2->subscribe(msgcontainer, 2); std::cout << "-----------------------------------------------" << std::endl; msgfield = "publisher: the publisher send this msg"; msg = new MsgImp(2, msgfield); publisher = new PublisherImp(); publisher->sendMsg(msgcontainer,msg); subscriber2->unsubscribe(msgcontainer,2); std::cout << "-----------------------------------------------" << std::endl; msgfield = "publisher: the publisher send this msg2"; msg = new MsgImp(2, msgfield); publisher = new PublisherImp(); publisher->sendMsg(msgcontainer, msg); return 0; }