C++ 中用于模块间通信的设计模式

C++ 中用于模块间通信的设计模式

1. 观察者模式 (Observer Pattern)

概念解释:定义对象间一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。

代码示例

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>

// 抽象观察者接口
class Observer {
public:
    virtual ~Observer() = default;
    virtual void update(const std::string& message) = 0;
};

// 具体观察者
class ModuleA : public Observer {
public:
    void update(const std::string& message) override {
        std::cout << "ModuleA 收到消息: " << message << std::endl;
    }
};

class ModuleB : public Observer {
public:
    void update(const std::string& message) override {
        std::cout << "ModuleB 处理消息: " << message << std::endl;
    }
};

// 主题(被观察者)
class Subject {
private:
    std::vector<Observer*> observers;
    std::string state;
    
public:
    void attach(Observer* observer) {
        observers.push_back(observer);
    }
    
    void detach(Observer* observer) {
        observers.erase(
            std::remove(observers.begin(), observers.end(), observer),
            observers.end()
        );
    }
    
    void notify() {
        for (auto* observer : observers) {
            observer->update(state);
        }
    }
    
    void setState(const std::string& newState) {
        state = newState;
        notify();
    }
};

// 使用示例
int main() {
    Subject subject;
    ModuleA moduleA;
    ModuleB moduleB;
    
    subject.attach(&moduleA);
    subject.attach(&moduleB);
    
    subject.setState("系统初始化完成");
    subject.setState("数据处理中...");
    
    return 0;
}

常见误区

  • 忘记在析构函数中清理观察者列表
  • 观察者更新顺序依赖可能导致死锁
  • 循环引用导致内存泄漏

2. 中介者模式 (Mediator Pattern)

概念解释:通过中介对象封装一系列对象间的交互,使对象间不直接相互引用,降低耦合度。

代码示例

cpp 复制代码
#include <iostream>
#include <string>
#include <unordered_map>
#include <memory>

// 前向声明
class Module;

// 中介者接口
class Mediator {
public:
    virtual ~Mediator() = default;
    virtual void sendMessage(const std::string& from, 
                           const std::string& to, 
                           const std::string& message) = 0;
    virtual void registerModule(const std::string& name, Module* module) = 0;
};

// 抽象模块基类
class Module {
protected:
    Mediator* mediator;
    std::string name;
    
public:
    Module(const std::string& n, Mediator* m) : name(n), mediator(m) {}
    virtual ~Module() = default;
    
    virtual void receive(const std::string& from, const std::string& message) = 0;
    void send(const std::string& to, const std::string& message) {
        mediator->sendMessage(name, to, message);
    }
    
    std::string getName() const { return name; }
};

// 具体中介者实现
class CommunicationMediator : public Mediator {
private:
    std::unordered_map<std::string, Module*> modules;
    
public:
    void registerModule(const std::string& name, Module* module) override {
        modules[name] = module;
    }
    
    void sendMessage(const std::string& from, 
                    const std::string& to, 
                    const std::string& message) override {
        if (modules.find(to) != modules.end()) {
            modules[to]->receive(from, message);
        } else {
            std::cout << "错误: 模块 " << to << " 不存在" << std::endl;
        }
    }
};

// 具体模块
class LoggerModule : public Module {
public:
    LoggerModule(const std::string& n, Mediator* m) : Module(n, m) {}
    
    void receive(const std::string& from, const std::string& message) override {
        std::cout << "[日志模块] 来自 " << from << ": " << message << std::endl;
    }
};

class ProcessorModule : public Module {
public:
    ProcessorModule(const std::string& n, Mediator* m) : Module(n, m) {}
    
    void receive(const std::string& from, const std::string& message) override {
        std::cout << "[处理模块] 处理来自 " << from << " 的数据: " << message << std::endl;
        // 处理后通知其他模块
        send("Logger", "数据处理完成");
    }
};

int main() {
    auto mediator = std::make_unique<CommunicationMediator>();
    
    LoggerModule logger("Logger", mediator.get());
    ProcessorModule processor("Processor", mediator.get());
    
    mediator->registerModule("Logger", &logger);
    mediator->registerModule("Processor", &processor);
    
    logger.send("Processor", "开始处理任务");
    
    return 0;
}

3. 发布-订阅模式 (Publisher-Subscriber Pattern)

概念解释:发布者不直接将消息发送给特定接收者,而是通过消息通道(总线)进行广播,订阅者只接收感兴趣的消息。

代码示例

cpp 复制代码
#include <iostream>
#include <functional>
#include <vector>
#include <unordered_map>
#include <string>
#include <memory>

// 事件基类
class Event {
public:
    virtual ~Event() = default;
    virtual std::string getType() const = 0;
};

// 具体事件
class DataEvent : public Event {
private:
    std::string data;
    
public:
    explicit DataEvent(const std::string& d) : data(d) {}
    std::string getType() const override { return "DATA_EVENT"; }
    std::string getData() const { return data; }
};

class ErrorEvent : public Event {
private:
    std::string errorMessage;
    
public:
    explicit ErrorEvent(const std::string& msg) : errorMessage(msg) {}
    std::string getType() const override { return "ERROR_EVENT"; }
    std::string getMessage() const { return errorMessage; }
};

// 订阅者接口
class Subscriber {
public:
    virtual ~Subscriber() = default;
    virtual void onEvent(const Event& event) = 0;
};

// 事件总线
class EventBus {
private:
    std::unordered_map<std::string, std::vector<Subscriber*>> subscribers;
    
public:
    void subscribe(const std::string& eventType, Subscriber* subscriber) {
        subscribers[eventType].push_back(subscriber);
    }
    
    void unsubscribe(const std::string& eventType, Subscriber* subscriber) {
        auto& list = subscribers[eventType];
        list.erase(std::remove(list.begin(), list.end(), subscriber), list.end());
    }
    
    void publish(const Event& event) {
        auto it = subscribers.find(event.getType());
        if (it != subscribers.end()) {
            for (auto* subscriber : it->second) {
                subscriber->onEvent(event);
            }
        }
    }
};

// 具体订阅者
class DataProcessor : public Subscriber {
public:
    void onEvent(const Event& event) override {
        if (event.getType() == "DATA_EVENT") {
            const auto& dataEvent = static_cast<const DataEvent&>(event);
            std::cout << "处理数据: " << dataEvent.getData() << std::endl;
        }
    }
};

class ErrorHandler : public Subscriber {
public:
    void onEvent(const Event& event) override {
        if (event.getType() == "ERROR_EVENT") {
            const auto& errorEvent = static_cast<const ErrorEvent&>(event);
            std::cout << "错误处理: " << errorEvent.getMessage() << std::endl;
        }
    }
};

int main() {
    EventBus bus;
    DataProcessor processor;
    ErrorHandler errorHandler;
    
    // 订阅感兴趣的事件
    bus.subscribe("DATA_EVENT", &processor);
    bus.subscribe("ERROR_EVENT", &errorHandler);
    
    // 发布事件
    DataEvent dataEvent("用户数据");
    ErrorEvent errorEvent("连接超时");
    
    bus.publish(dataEvent);
    bus.publish(errorEvent);
    
    return 0;
}

4. 命令模式 (Command Pattern)

概念解释:将请求封装为对象,使你可以用不同的请求参数化其他对象,并支持请求的排队、日志记录、撤销等操作。

代码示例

cpp 复制代码
#include <iostream>
#include <memory>
#include <vector>
#include <queue>

// 命令接口
class Command {
public:
    virtual ~Command() = default;
    virtual void execute() = 0;
    virtual void undo() = 0;
};

// 接收者
class CommunicationModule {
public:
    void sendData(const std::string& data) {
        std::cout << "发送数据: " << data << std::endl;
    }
    
    void receiveData(const std::string& data) {
        std::cout << "接收数据: " << data << std::endl;
    }
};

// 具体命令
class SendCommand : public Command {
private:
    CommunicationModule* receiver;
    std::string data;
    
public:
    SendCommand(CommunicationModule* rec, const std::string& d) 
        : receiver(rec), data(d) {}
    
    void execute() override {
        receiver->sendData(data);
    }
    
    void undo() override {
        std::cout << "撤销发送操作" << std::endl;
    }
};

class ReceiveCommand : public Command {
private:
    CommunicationModule* receiver;
    std::string data;
    
public:
    ReceiveCommand(CommunicationModule* rec, const std::string& d) 
        : receiver(rec), data(d) {}
    
    void execute() override {
        receiver->receiveData(data);
    }
    
    void undo() override {
        std::cout << "撤销接收操作" << std::endl;
    }
};

// 调用者
class Invoker {
private:
    std::queue<std::shared_ptr<Command>> commandQueue;
    std::vector<std::shared_ptr<Command>> history;
    
public:
    void addCommand(std::shared_ptr<Command> cmd) {
        commandQueue.push(cmd);
    }
    
    void executeCommands() {
        while (!commandQueue.empty()) {
            auto cmd = commandQueue.front();
            commandQueue.pop();
            cmd->execute();
            history.push_back(cmd);
        }
    }
    
    void undoLast() {
        if (!history.empty()) {
            history.back()->undo();
            history.pop_back();
        }
    }
};

int main() {
    CommunicationModule module;
    Invoker invoker;
    
    invoker.addCommand(std::make_shared<SendCommand>(&module, "Hello"));
    invoker.addCommand(std::make_shared<ReceiveCommand>(&module, "World"));
    invoker.addCommand(std::make_shared<SendCommand>(&module, "Test"));
    
    invoker.executeCommands();
    invoker.undoLast();
    
    return 0;
}

5. 外观模式 (Facade Pattern)

概念解释:为子系统中的一组接口提供一个统一的高层接口,简化模块间的复杂交互。

代码示例

cpp 复制代码
#include <iostream>
#include <string>

// 子系统类
class NetworkManager {
public:
    void connect() { std::cout << "网络连接建立" << std::endl; }
    void disconnect() { std::cout << "网络连接断开" << std::endl; }
    void send(const std::string& data) { 
        std::cout << "网络发送: " << data << std::endl; 
    }
};

class DataSerializer {
public:
    std::string serialize(const std::string& data) {
        return "[序列化]" + data;
    }
    std::string deserialize(const std::string& data) {
        return data.substr(6); // 移除标记
    }
};

class SecurityManager {
public:
    std::string encrypt(const std::string& data) {
        return "[加密]" + data;
    }
    std::string decrypt(const std::string& data) {
        return data.substr(4); // 移除标记
    }
};

// 外观类
class CommunicationFacade {
private:
    NetworkManager network;
    DataSerializer serializer;
    SecurityManager security;
    
public:
    void sendMessage(const std::string& message) {
        std::cout << "发送消息流程开始..." << std::endl;
        
        // 连接网络
        network.connect();
        
        // 加密数据
        std::string encrypted = security.encrypt(message);
        
        // 序列化
        std::string serialized = serializer.serialize(encrypted);
        
        // 发送
        network.send(serialized);
        
        // 断开连接
        network.disconnect();
        
        std::cout << "消息发送完成" << std::endl;
    }
    
    std::string receiveMessage(const std::string& data) {
        std::cout << "接收消息流程开始..." << std::endl;
        
        // 连接网络
        network.connect();
        
        // 反序列化
        std::string deserialized = serializer.deserialize(data);
        
        // 解密
        std::string decrypted = security.decrypt(deserialized);
        
        // 断开连接
        network.disconnect();
        
        std::cout << "消息接收完成" << std::endl;
        return decrypted;
    }
};

int main() {
    CommunicationFacade facade;
    
    facade.sendMessage("Hello, World!");
    
    std::string received = facade.receiveMessage("[序列化][加密]Hello, World!");
    std::cout << "最终消息: " << received << std::endl;
    
    return 0;
}

底层实现机制

观察者模式 vs 发布-订阅模式

  • 观察者模式:直接耦合,观察者知道被观察者
  • 发布-订阅模式:通过消息总线解耦,发布者和订阅者互不知道对方存在

性能考虑

  1. 同步 vs 异步

    • 同步:阻塞调用,简单但可能影响性能
    • 异步:非阻塞,需要处理线程安全
  2. 内存管理

    cpp 复制代码
    // 智能指针防止内存泄漏
    std::shared_ptr<Observer> observer = std::make_shared<ModuleA>();
    
    // 弱指针打破循环引用
    std::weak_ptr<Observer> weakObserver = observer;

应用建议

  1. 简单通信:观察者模式
  2. 复杂系统:发布-订阅 + 中介者模式
  3. 需要解耦:外观模式 + 命令模式
  4. 异步通信:生产者-消费者模式 + 线程池
  5. 分布式系统:消息队列(如ZeroMQ、RabbitMQ集成)
相关推荐
8Qi82 小时前
LeetCode热题100--189
c语言·数据结构·c++·算法·leetcode
灰色小旋风2 小时前
力扣第八题C++ 字符串转换整数
c++·算法·leetcode
王的宝库2 小时前
Go 语言基础进阶:指针、init、匿名函数/闭包、defer
开发语言·go
Qt程序员2 小时前
Linux .so 动态库:底层原理
linux·c++·内核·动态库
灰色小旋风2 小时前
力扣第十题C++正则表达式匹配
c++·leetcode·正则表达式
乌萨奇也要立志学C++2 小时前
【Linux】线程池(一)C++ 手写线程池:基于策略模式实现高性能日志模块
linux·c++·策略模式
蜜獾云2 小时前
设计模式之简单工厂模式(4):创建对象时不会暴露创建逻辑
java·设计模式·简单工厂模式
lihaihui19912 小时前
Linux C++知识梳理
linux·c++
进击的荆棘2 小时前
优选算法——模拟
java·开发语言·算法·模拟