心胸决定格局,眼界决定境界...

消息总线

消息总线模式 == 等价于 发布-订阅模式
消息总线 == 事件处理中心
观察者应该主动向消息总线注册事件,因为消息总线并不知道哪些对象需要别注册。
当主题发生变化时,主动向消息总线发送消息。
消息总线会找到关注指定消息的所有观察者,进行通告,观察者做出行动。
 
Observer Message Bus Subject
 
对上述的例子进行改写:
1.观察者应该主动向消息总线注册消息
2.消息与observer绑定,用数据结构unordered_multimap包维持

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
Message.h
#pragma once
enum  Message {
    kAdd,
    kSub,
    kMul,
    kDiv
};
 
inline std::string ToMessageString(Message event) {//inline 内部链接
    switch (event) {
    case 0:
        return "add operation";
        break;
    case 1:
        return "sub operation";
        break;
    case 2:
        return "mul operation";
        break;
    case 3:
        return "div operation";
        break;
    }
}
 
subscriber.h
#pragma once
#include <string>
#include "Message.h"
class MessageBus;
class Subscriber
{
public:
    Subscriber(std::string name, Message event);
    void RegisterMessage(MessageBus* bus);
private:
    std::string name_;
    Message interested_event_;
};
 
subscriber.cpp
#include "subscriber.h"
#include "MessageBus.h"
#include<iostream>
 
Subscriber::Subscriber(std::string name, Message event)
{
    name_ = name;
    interested_event_ = event;
    std::cout << name_ << " subscribe " << ToMessageString(interested_event_) << std::endl;
}
 
void Subscriber::RegisterMessage(MessageBus* bus)
{
    auto func = [=]() {std::cout << name_ << " response " << ToMessageString(interested_event_) << std::endl;  };
    bus->AddMessage(interested_event_, func);
}
 
MessageBus.h
#include "subscriber.h"
#include "Message.h"
class Subscriber;
class MessageBus
{
public:
    void Notify(Message event);
    void AddMessage(Message event, std::function<void()> handler);//Handle  Message
private:
    std::unordered_multimap<Message, std::function<void()>>   observers;
};
 
MessageBus.cpp
#include "MessageBus.h"
 
void MessageBus::Notify(Message event)
{
    auto iterators = observers.find(event);
    auto range = observers.equal_range(event);
    for (auto it = range.first; it != range.second; it++) {
        it->second();
    }
     
}
void MessageBus::AddMessage(Message event, std::function<void()> handler)
{
    observers.emplace(event, handler);
}
 
publisher.h
#pragma once
#include <string>
#include "Message.h"
class MessageBus;
class Publisher
{
public:
    void Publish(MessageBus* center, Message event);
};
 
publisher.cpp
#include "publisher.h"
#include "MessageBus.h"
#include <iostream>
#include <string>
 
void Publisher::Publish(MessageBus* center, Message event)
{
    std::cout << " publish : " << ToMessageString(event) << " message " << std::endl;
    center->Notify(event);
}
 
void test_MessageBus()
{
 
    Subscriber member_1("Alen", Message::kAdd);
    Subscriber member_2("Bob",  Message::kSub);
    Subscriber member_3("Sam",  Message::kAdd);
 
    MessageBus bus;
 
    //Register
    member_1.RegisterMessage(&bus);
    member_2.RegisterMessage(&bus);
    member_3.RegisterMessage(&bus);
 
    Publisher message_1;
    message_1.Publish(&bus, Message::kSub);
    message_1.Publish(&bus, Message::kDiv);
    message_1.Publish(&bus, Message::kAdd);
}

  

posted @   WELEN  阅读(426)  评论(0编辑  收藏  举报
编辑推荐:
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
阅读排行:
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· 深度对比:PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
点击右上角即可分享
微信分享提示