消息总线

消息总线模式 == 等价于 发布-订阅模式
消息总线 == 事件处理中心
观察者应该主动向消息总线注册事件,因为消息总线并不知道哪些对象需要别注册。
当主题发生变化时,主动向消息总线发送消息。
消息总线会找到关注指定消息的所有观察者,进行通告,观察者做出行动。
 
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);
}

  

原文地址:https://www.cnblogs.com/welen/p/14550059.html