您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# C++怎么实现发布订阅和观察者模式
## 1. 模式概述
### 1.1 观察者模式
观察者模式(Observer Pattern)定义了对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动收到通知。
### 1.2 发布订阅模式
发布订阅模式(Pub-Sub Pattern)是观察者模式的变体,通过引入消息代理(Broker)解耦发布者和订阅者,双方不直接通信。
### 1.3 核心区别
| 特性 | 观察者模式 | 发布订阅模式 |
|---------------|-------------------|-------------------|
| 耦合度 | 松耦合 | 完全解耦 |
| 通信方式 | 直接通知 | 通过消息代理 |
| 实时性 | 高 | 可能延迟 |
| 实现复杂度 | 简单 | 较复杂 |
## 2. 观察者模式实现
### 2.1 经典实现
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
// 观察者接口
class Observer {
public:
virtual ~Observer() = default;
virtual void update(const std::string& message) = 0;
};
// 主题接口
class Subject {
public:
virtual ~Subject() = default;
virtual void attach(Observer* observer) = 0;
virtual void detach(Observer* observer) = 0;
virtual void notify(const std::string& message) = 0;
};
// 具体主题
class ConcreteSubject : public Subject {
std::vector<Observer*> observers_;
public:
void attach(Observer* observer) override {
observers_.push_back(observer);
}
void detach(Observer* observer) override {
observers_.erase(
std::remove(observers_.begin(), observers_.end(), observer),
observers_.end()
);
}
void notify(const std::string& message) override {
for (auto observer : observers_) {
observer->update(message);
}
}
};
// 具体观察者
class ConcreteObserver : public Observer {
std::string name_;
public:
explicit ConcreteObserver(const std::string& name) : name_(name) {}
void update(const std::string& message) override {
std::cout << name_ << " received: " << message << std::endl;
}
};
// 使用示例
int main() {
ConcreteSubject subject;
ConcreteObserver observer1("Observer1");
ConcreteObserver observer2("Observer2");
subject.attach(&observer1);
subject.attach(&observer2);
subject.notify("First Notification");
subject.detach(&observer1);
subject.notify("Second Notification");
return 0;
}
#include <memory>
#include <vector>
#include <functional>
class Subject {
std::vector<std::function<void(const std::string&)>> callbacks_;
public:
void attach(std::function<void(const std::string&)> callback) {
callbacks_.push_back(callback);
}
void notify(const std::string& message) {
for (const auto& cb : callbacks_) {
cb(message);
}
}
};
// 使用lambda表达式注册观察者
int main() {
Subject subject;
auto observer1 = [](const std::string& msg) {
std::cout << "Observer1: " << msg << std::endl;
};
subject.attach(observer1);
subject.attach([](const std::string& msg) {
std::cout << "Observer2: " << msg << std::endl;
});
subject.notify("Event occurred!");
return 0;
}
#include <map>
#include <vector>
#include <string>
#include <functional>
class PubSub {
std::map<std::string, std::vector<std::function<void(const std::string&)>>> topics_;
public:
void subscribe(const std::string& topic,
std::function<void(const std::string&)> callback) {
topics_[topic].push_back(callback);
}
void publish(const std::string& topic, const std::string& message) {
if (topics_.find(topic) != topics_.end()) {
for (const auto& callback : topics_[topic]) {
callback(message);
}
}
}
};
int main() {
PubSub pubsub;
// 订阅主题
pubsub.subscribe("news", [](const std::string& msg) {
std::cout << "Subscriber1 received news: " << msg << std::endl;
});
pubsub.subscribe("sports", [](const std::string& msg) {
std::cout << "Subscriber2 received sports: " << msg << std::endl;
});
// 发布消息
pubsub.publish("news", "New C++20 features released!");
pubsub.publish("sports", "Team won the championship");
return 0;
}
#include <mutex>
#include <shared_mutex>
class ThreadSafePubSub {
std::map<std::string, std::vector<std::function<void(const std::string&)>>> topics_;
mutable std::shared_mutex mutex_;
public:
void subscribe(const std::string& topic,
std::function<void(const std::string&)> callback) {
std::unique_lock lock(mutex_);
topics_[topic].push_back(callback);
}
void publish(const std::string& topic, const std::string& message) {
std::shared_lock lock(mutex_);
auto it = topics_.find(topic);
if (it != topics_.end()) {
// 复制回调列表以避免锁持有期间执行用户代码
auto callbacks = it->second;
lock.unlock();
for (const auto& callback : callbacks) {
callback(message);
}
}
}
};
回调存储优化:
std::vector
存储回调函数线程模型选择:
std::shared_mutex
)内存管理:
std::shared_ptr
管理观察者生命周期避免回调阻塞:
创建可配置的事件发布/订阅系统
class EventSystemFactory {
public:
static std::unique_ptr<PubSub> createSimple() {
return std::make_unique<PubSub>();
}
static std::unique_ptr<PubSub> createThreadSafe() {
return std::make_unique<ThreadSafePubSub>();
}
};
实现带日志记录功能的发布订阅系统
class LoggingPubSubDecorator : public PubSub {
PubSub& wrapped_;
public:
explicit LoggingPubSubDecorator(PubSub& wrapped) : wrapped_(wrapped) {}
void publish(const std::string& topic, const std::string& message) override {
std::cout << "Publishing to " << topic << ": " << message << std::endl;
wrapped_.publish(topic, message);
}
};
std::weak_ptr
打破循环本文详细介绍了在C++中实现观察者模式和发布订阅模式的方法。观察者模式适合紧密耦合的场景,而发布订阅模式更适合分布式系统。现代C++特性(如lambda、智能指针等)可以大幅简化实现代码。在实际应用中,应根据具体需求选择合适的模式,并注意线程安全和性能优化问题。
两种模式的本质都是实现事件驱动架构,是构建响应式系统的重要工具。掌握这些模式可以帮助开发者设计出更灵活、更易维护的系统架构。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。