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