C++发布订阅模式
发布订阅模式主要包含三个部分:消息发布、消息订阅者、消息处理中心。与观察者模式相比多出了消息处理中心模块,这样在结构上可以解耦订阅者与发布者,功能上更加的丰富。
观察者模式
结构设计
- 有一个消息list,主线程向这个list尾部追加消息,同时另一个子线程从消息list头部不断取出第一个消息
- 查找消息订阅map,订阅者与消息设计为n:n关系,一个消息可被多个订阅者订阅,因此需依次执行订阅了这个消息的函数
- 如:Stocks Trade消息需被Suber1和Suber4两个订阅者处理
简单来说就是:EventDeta*就是一个数据,并为之取了一个别名 * Trade,称之为消息。而很多类函数(普通函数也一样的)的正常执行需要这个EventData,因此这个类将其某个函数和EventData通过订阅列表绑定,当这个EventData也即是消息成为消息列表的第一个元素时,就执行和这个EventData绑定的所有类函数。
代码
[知乎]](https://zhuanlan.zhihu.com/p/484171260)
消息发布
EventData.h:
/*
定义有哪些消息、消息对应的数据
当想要发自己的消息,可以在这里进行添加
*/
// 消息句柄用于标识消息
char * event_data1 = "Stocks Trade";
// 消息主体,可做为订阅者的入参,以对此消息进行处理
struct EventData1
{
int e = 0;
};
char * event_data2 = "Bonds Trade";
struct EventData2
{
char * i = "receiver";
};
char * event_data3 = "Funds Trade";
struct EventData3
{
EventData1 data1;
EventData2 data2;
};
消息订阅者
EventSuber.h: 订阅者消息处理函数一般接收两个参数,一个是自己的参数,一个是传过来的消息
这里可以不申明类,直接写三个消息处理函数也可以
#include"EventData.h"
#include
#include
using namespace std; // string是标准卡函数
/*订阅消息处理模块 3个 */
class Subscriber1
{
public:
// 利用静态成员函数,保留上一次消息处理结果
// 不能访问非静态成员变量与非静态成员函数 => 传这个类的指针 void* _this
// 强转_this指针,调用此类的成员函数、成员变量 _this=&(Subscriber1实例)
// 给这个订阅器传一个消息
static void HandleReceiveEvent (void * _this, void * data)
{
Subscriber1 * th = (Subscriber1 *)_this;
EventData1* d = (EventData1 *)data;
d->e += th->_data;
printf("%s, data:%d \n",__FUNCTION__,d->e);
}
int _data = 10;
};
class Subscriber2
{
public:
static void HandleReceiveEvent (void * _this, void * data)
{
Subscriber2 * th = (Subscriber2 *)_this;
EventData2* d = (EventData2 *)data;
string str(d->i);
str += th->_data;
printf("%s, data:%s \n",__FUNCTION__,str.c_str());
}
char * _data = " Subscriber 2";
};
class Subscriber3
{
public:
static void HandleReceiveEvent (void * _this, void * data)
{
Subscriber3 * th = (Subscriber3 *)_this;
EventData3* d = (EventData3 *)data;
d->data1.e += th->_data1;
string str(d->data2.i);
str += th->_data2;
printf("%s, data:%d , %s \n",__FUNCTION__,d->data1.e,str.c_str());
}
int _data1 = 30;
char * _data2 = " Subscriber 3";
};
消息处理中心
EventDeal.h: 开启一个子线程,不断去消息list取消息,并将该消息将由所有订阅者进行处理
#include
#include
main线程
添加三个消息,并分别添加如顶图所示的订阅者(订阅者4换成订阅者1)
#include
#include