对于上一文章中的状态机设计,其实已经是有个中介者模式,状态机为:

1. 观察者模式 / 发布-订阅模式

2. 生产者-消费者模式

3. 状态模式(State Pattern)

4.中介者模式”的雏形

接下来介绍这个中介者模式:

一、定义

中介者模式是一种行为型设计模式,用一个中心对象(中介者)来封装多个对象之间的交互逻辑,避免这些对象互相强耦合,从而让对象之间的通信通过中介者来完成。

简单说:

  • 不让各个模块直接互相调用,而是都通过一个**“中央调度员”**去协调它们。
  • 这个中央调度员就是中介者(Mediato)。

二、为什么要有它?

在系统里,如果多个模块之间直接互相调用,会出现:

  • 依赖关系复杂,耦合度高
  • 扩展或修改一个模块时,可能影响其他多个模块
  • 难以维护和调试

引入中介者模式后:

  • 模块之间不再直接联系,只需要知道中介者接口。
  • 中介者负责收集信息、分发命令、组织通信。
  • 模块新增或删除,其他模块基本不用改,改中介者即可。

三、现实例子

现实中类似的场景很多:

  1. 机场塔台调度

    飞机之间不直接联系彼此,而是通过塔台(中介者)传递起降信息和指令。
  2. 聊天室

    用户之间不直接发消息,而是通过聊天室服务器(中介者)转发给目标用户。
  3. 嵌入式设备总控

    在嵌入式系统里,不同功能模块(传感器采集、通信模块、显示模块)不直接调用对方控制函数,而是通过一个总控调度对象协调,比如任务调度器、消息总线。

四、优点

  1. 降低耦合:各模块不直接交互,只和中介者交互。
  2. 集中控制逻辑:通信逻辑集中在中介者里,更清晰、更易维护。
  3. 可扩展性强:增加新模块时,只需要改中介者,不必改其他模块。

五、嵌入式相关示例代码

我们假设一个嵌入式系统有:

  • 温度传感器模块 Sensor
  • 通信模块 Comm
  • 显示模块 Display
    它们之间要协作:
  • 传感器采集数据 → 通信模块发送 → 显示模块更新画面
    我们用中介者模式实现。

c++版本:

#include <iostream>
#include <string>

// 中介者接口
class Mediator {
public:
    virtual void sendMessage(const std::string& msg, const std::string& from) = 0;
};

// 具体模块的抽象基类
class Module {
protected:
    Mediator* mediator;
public:
    Module(Mediator* m) : mediator(m) {}
};

// 温度传感器模块
class Sensor : public Module {
public:
    Sensor(Mediator* m) : Module(m) {}
    void readTemperature(float temp) {
        std::string msg = "TEMP:" + std::to_string(temp);
        mediator->sendMessage(msg, "Sensor");
    }
};

// 通信模块
class Comm : public Module {
public:
    Comm(Mediator* m) : Module(m) {}
    void sendData(const std::string& data) {
        std::cout << "[Comm] Sending data: " << data << std::endl;
    }
};

// 显示模块
class Display : public Module {
public:
    Display(Mediator* m) : Module(m) {}
    void updateScreen(const std::string& data) {
        std::cout << "[Display] Screen shows: " << data << std::endl;
    }
};

// 具体中介者
class ConcreteMediator : public Mediator {
private:
    Sensor* sensor;
    Comm* comm;
    Display* display;
public:
    void setSensor(Sensor* s) { sensor = s; }
    void setComm(Comm* c) { comm = c; }
    void setDisplay(Display* d) { display = d; }

    void sendMessage(const std::string& msg, const std::string& from) override {
        if (from == "Sensor") {
            comm->sendData(msg);     // 传感器数据给通信模块
            display->updateScreen(msg); // 同时更新显示
        }
    }
};

int main() {
    ConcreteMediator mediator;
    Sensor sensor(&mediator);
    Comm comm(&mediator);
    Display display(&mediator);

    mediator.setSensor(&sensor);
    mediator.setComm(&comm);
    mediator.setDisplay(&display);

    // 模拟温度读取
    sensor.readTemperature(26.5);
    return 0;
}

输出结果

[Comm] Sending data: TEMP:26.500000
[Display] Screen shows: TEMP:26.500000

c语言

#include <stdio.h>
#include <string.h>

// 模块接口
typedef struct Mediator Mediator;

typedef struct {
    Mediator* mediator;
} Sensor;

typedef struct {
    Mediator* mediator;
} Comm;

typedef struct {
    Mediator* mediator;
} Display;

// 中介者结构体
struct Mediator {
    Sensor* sensor;
    Comm* comm;
    Display* display;

    void (*sendMessage)(Mediator*, const char* msg, const char* from);
};

// 模块函数
void sensor_readTemperature(Sensor* s, float temp) {
    char msg[32];
    sprintf(msg, "TEMP:%.2f", temp);
    s->mediator->sendMessage(s->mediator, msg, "Sensor");
}

void comm_sendData(Comm* c, const char* data) {
    printf("[Comm] Sending data: %s\n", data);
}

void display_update(Display* d, const char* data) {
    printf("[Display] Screen shows: %s\n", data);
}

// 中介者具体实现
void mediator_sendMessage(Mediator* m, const char* msg, const char* from) {
    if (strcmp(from, "Sensor") == 0) {
        comm_sendData(m->comm, msg);
        display_update(m->display, msg);
    }
}

int main() {
    // 创建模块和中介者
    Mediator mediator = {0};
    Sensor sensor = {&mediator};
    Comm comm = {&mediator};
    Display display = {&mediator};

    mediator.sensor = &sensor;
    mediator.comm = &comm;
    mediator.display = &display;
    mediator.sendMessage = mediator_sendMessage;

    // 模拟温度采集
    sensor_readTemperature(&sensor, 26.5);

    return 0;
}

输出结果:

[Comm] Sending data: TEMP:26.50
[Display] Screen shows: TEMP:26.50

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐