如何解决发布具有不同内容的订阅消息
嗨,我正在尝试实现pub / sub模式,当消息具有不同的内容类型时,我对实现此模式几乎没有疑问。我的第一种方法(使用单个类型的消息(在这种情况下为字符串))如下:
#pragma once
#include <functional>
#include <list>
#include <memory>
#include <tuple>
#include <unordered_map>
class Broker {
private:
bool is_running;
std::unordered_map<TOPIC,std::list<std::function<void(const Message &)>>>
subscriptions;
static inline std::shared_ptr<Broker> instance{nullptr};
Broker() {}
public:
~Broker() {}
static std::shared_ptr<Broker> getInstance() {
if (instance.get() == nullptr) {
instance = std::make_shared<Broker>(Broker());
}
return instance;
}
void subscribe(const TOPIC &topic,const std::function<void(const Message&)> &callback) {
if (subscriptions.find(topic) == subscriptions.end()) {
subscriptions.insert({topic,std::list{callback}});
} else {
subscriptions[topic].push_back(callback);
}
}
void publish(const Message &message) {
if (subscriptions.find(message.get_topic()) != subscriptions.end()) {
for (auto const &call : subscriptions[message.get_topic()]) {
call(message);
}
}
}
};
// message
#include <string>
enum TOPIC { TOPIC_A,TOPIC_B,TOPIC_C };
class Message {
private:
TOPIC topic;
std::string content;
public:
Message(TOPIC topic,const std::string &content) : topic{topic},content{content} {}
TOPIC get_topic() const { return this->topic; }
std::string get_content() const { return this->content; }
};
// in a subscriber
...
broker->subscribe(TOPIC::TOPIC_A,std::bind(...);
broker->subscribe(TOPIC::TOPIC_B,std::bind(...);
...
// in a publisher
....
broker->publish(Message{TOPIC::TOPIC_A,std::string{"some message"});
broker->publish(Message{TOPIC::TOPIC_A,std::string{"other message"});
...
然后我意识到我需要具有不同内容类型的消息,因此我尝试重构代码,这就是我所拥有的:
#pragma once
#include <functional>
#include <list>
#include <memory>
#include <tuple>
#include <unordered_map>
template <class Content>
class Broker {
private:
bool is_running;
std::unordered_map<TOPIC,std::list<std::function<void(const Message<Content> &)>>>
subscriptions;
static inline std::shared_ptr<Broker> instance{nullptr};
Broker() {}
public:
~Broker() {}
static std::shared_ptr<Broker> getInstance() {
if (instance.get() == nullptr) {
instance = std::make_shared<Broker>(Broker());
}
return instance;
}
void subscribe(const TOPIC &topic,const std::function<void(const Message<Content> &)> &callback) {
if (subscriptions.find(topic) == subscriptions.end()) {
subscriptions.insert({topic,std::list{callback}});
} else {
subscriptions[topic].push_back(callback);
}
}
void publish(const Message<Content> &message) {
if (subscriptions.find(message.get_topic()) != subscriptions.end()) {
for (auto const &call : subscriptions[message.get_topic()]) {
call(message);
}
}
}
};
// message
template <class Content> class Message {
private:
TOPIC topic;
Content content;
public:
Message(TOPIC topic,const Content &content) : topic{topic},content{content} {}
TOPIC get_topic() const { return this->topic; }
Content get_content() const { return this->content; }
};
// in a subscriber
...
std::shared_ptr<Broker<std::string>> broker =
Broker<std::string>::getInstance();
broker->subscribe(TOPIC::TOPIC_A,std::bind(...));
std::shared_ptr<Broker<int>> broker1 =
Broker<int>::getInstance();
broker1->subscribe(TOPIC::TOPIC_B,std::bind(...));
...
因此,现在每次需要具有不同内容类型的消息时,我都必须创建一个不同的Broker。我在打破格局吗?是否有更好(更标准/更有效)的方法来解决此问题?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。