消息总线
消息总线模式 == 等价于 发布-订阅模式
消息总线 == 事件处理中心
观察者应该主动向消息总线注册事件,因为消息总线并不知道哪些对象需要别注册。
当主题发生变化时,主动向消息总线发送消息。
消息总线会找到关注指定消息的所有观察者,进行通告,观察者做出行动。
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); } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· 深度对比:PostgreSQL 和 SQL Server 在统计信息维护中的关键差异