设计模式之中介者模式

1 概念定义

中介者模式是一种行为型设计模式,它定义一个中介对象来封装一组对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,并且可以独立地改变它们之间的交互。

2 核心思想:

对象解耦:将多对多的交互关系转换为一对多的关系

集中控制:将对象间的交互逻辑集中在中介者中

通信中枢:对象之间不直接通信,而是通过中介者进行

降低复杂度:减少对象间的相互依赖,使系统更易于维护

3 主要角色:

  • Mediator(抽象中介者):定义同事对象到中介者的接口

  • ConcreteMediator(具体中介者):实现中介者接口,协调各个同事对象的交互

  • Colleague(抽象同事类):定义同事类的接口,持有中介者的引用

  • ConcreteColleague(具体同事类):实现同事类接口,通过中介者与其他同事通信

4 应用场景

以航空管制系统为例:

机场有多架飞机需要起降

飞机之间不能直接通信

需要统一的塔台来协调所有飞机的起降

塔台需要管理跑道使用、飞行顺序、紧急情况等

每架飞机只需要与塔台通信,不需要了解其他飞机的状态

5 UML

6 C++代码实现

cpp 复制代码
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <algorithm>
#include <queue>
#include <chrono>
#include <thread>
using namespace std;

// 前向声明
class Aircraft;
class ControlTower;

// ========== 飞行状态枚举 ==========
enum class FlightStatus {
    ON_GROUND,      // 在地面
    TAXIING,        // 滑行
    WAITING_TAKEOFF, // 等待起飞
    TAKING_OFF,     // 起飞中
    AIRBORNE,       // 在空中
    APPROACHING,    // 进近中
    WAITING_LANDING, // 等待降落
    LANDING         // 降落中
};

// ========== 飞机类型枚举 ==========
enum class AircraftType {
    PASSENGER,      // 客机
    CARGO,          // 货机
    PRIVATE,        // 私人飞机
    MILITARY        // 军用机
};

// ========== 抽象同事类:飞机 ==========
class Aircraft {
protected:
    string flightNumber;
    AircraftType type;
    FlightStatus status;
    int fuelLevel;          // 燃油量(分钟)
    int priority;           // 优先级(数字越大越优先)
    ControlTower* tower;    // 中介者引用
    
public:
    Aircraft(const string& number, AircraftType t, int fuel, int prio)
        : flightNumber(number), type(t), status(FlightStatus::ON_GROUND),
          fuelLevel(fuel), priority(prio), tower(nullptr) {}
    
    virtual ~Aircraft() = default;
    
    // 设置中介者
    void setMediator(ControlTower* t) { tower = t; }
    
    // 获取飞机信息
    string getFlightNumber() const { return flightNumber; }
    AircraftType getType() const { return type; }
    FlightStatus getStatus() const { return status; }
    int getFuelLevel() const { return fuelLevel; }
    int getPriority() const { return priority; }
    
    // 更新状态
    void setStatus(FlightStatus newStatus) {
        cout << "飞机 " << flightNumber << " 状态变更为: " << statusToString(newStatus) << endl;
        status = newStatus;
    }
    
    // 燃油消耗
    void consumeFuel(int minutes) {
        fuelLevel -= minutes;
        if (fuelLevel < 0) fuelLevel = 0;
    }
    
    // 检查是否需要紧急处理
    bool isEmergency() const {
        return fuelLevel < 30;  // 燃油少于30分钟视为紧急
    }
    
    // 状态转字符串
    string statusToString(FlightStatus s) const {
        switch(s) {
            case FlightStatus::ON_GROUND: return "在地面";
            case FlightStatus::TAXIING: return "滑行";
            case FlightStatus::WAITING_TAKEOFF: return "等待起飞";
            case FlightStatus::TAKING_OFF: return "起飞中";
            case FlightStatus::AIRBORNE: return "在空中";
            case FlightStatus::APPROACHING: return "进近中";
            case FlightStatus::WAITING_LANDING: return "等待降落";
            case FlightStatus::LANDING: return "降落中";
            default: return "未知";
        }
    }
    
    string typeToString() const {
        switch(type) {
            case AircraftType::PASSENGER: return "客机";
            case AircraftType::CARGO: return "货机";
            case AircraftType::PRIVATE: return "私人飞机";
            case AircraftType::MILITARY: return "军用机";
            default: return "未知";
        }
    }
    
    // 飞机行为(通过中介者通信)
    virtual void requestTakeoff() = 0;
    virtual void requestLanding() = 0;
    virtual void receiveClearance(const string& clearance) = 0;
    virtual void reportPosition() = 0;
};

// ========== 抽象中介者:控制塔台 ==========
class ControlTower {
public:
    virtual ~ControlTower() = default;
    
    // 注册飞机
    virtual void registerAircraft(Aircraft* aircraft) = 0;
    
    // 移除飞机
    virtual void unregisterAircraft(const string& flightNumber) = 0;
    
    // 处理起飞请求
    virtual void processTakeoffRequest(Aircraft* aircraft) = 0;
    
    // 处理降落请求
    virtual void processLandingRequest(Aircraft* aircraft) = 0;
    
    // 广播消息
    virtual void broadcastMessage(const string& message, Aircraft* sender = nullptr) = 0;
    
    // 处理紧急情况
    virtual void handleEmergency(Aircraft* aircraft) = 0;
    
    // 分配跑道
    virtual bool allocateRunway(Aircraft* aircraft) = 0;
    
    // 释放跑道
    virtual void releaseRunway(Aircraft* aircraft) = 0;
    
    // 获取塔台状态
    virtual void getStatus() const = 0;
};

// ========== 具体同事类:客机 ==========
class PassengerAircraft : public Aircraft {
public:
    PassengerAircraft(const string& number, int fuel, int prio = 1)
        : Aircraft(number, AircraftType::PASSENGER, fuel, prio) {}
    
    void requestTakeoff() override {
        cout << "【客机" << flightNumber << "】请求起飞,乘客人数: 200,燃油: " 
             << fuelLevel << "分钟" << endl;
        if (tower) {
            tower->processTakeoffRequest(this);
        }
    }
    
    void requestLanding() override {
        cout << "【客机" << flightNumber << "】请求降落,燃油剩余: " 
             << fuelLevel << "分钟" << endl;
        if (tower) {
            tower->processLandingRequest(this);
        }
    }
    
    void receiveClearance(const string& clearance) override {
        cout << "【客机" << flightNumber << "】收到指令: " << clearance << endl;
        if (clearance.find("起飞") != string::npos) {
            setStatus(FlightStatus::TAKING_OFF);
        } else if (clearance.find("降落") != string::npos) {
            setStatus(FlightStatus::LANDING);
        }
    }
    
    void reportPosition() override {
        cout << "【客机" << flightNumber << "】当前位置: 高度10000米,速度800km/h" << endl;
    }
};

// ========== 具体同事类:货机 ==========
class CargoAircraft : public Aircraft {
public:
    CargoAircraft(const string& number, int fuel, int prio = 2)
        : Aircraft(number, AircraftType::CARGO, fuel, prio) {}
    
    void requestTakeoff() override {
        cout << "【货机" << flightNumber << "】请求起飞,货物重量: 50吨,燃油: " 
             << fuelLevel << "分钟" << endl;
        if (tower) {
            tower->processTakeoffRequest(this);
        }
    }
    
    void requestLanding() override {
        cout << "【货机" << flightNumber << "】请求降落,燃油剩余: " 
             << fuelLevel << "分钟" << endl;
        if (tower) {
            tower->processLandingRequest(this);
        }
    }
    
    void receiveClearance(const string& clearance) override {
        cout << "【货机" << flightNumber << "】收到指令: " << clearance << endl;
    }
    
    void reportPosition() override {
        cout << "【货机" << flightNumber << "】当前位置: 高度8000米,速度700km/h" << endl;
    }
};

// ========== 具体同事类:私人飞机 ==========
class PrivateAircraft : public Aircraft {
public:
    PrivateAircraft(const string& number, int fuel, int prio = 0)
        : Aircraft(number, AircraftType::PRIVATE, fuel, prio) {}
    
    void requestTakeoff() override {
        cout << "【私人飞机" << flightNumber << "】请求起飞,燃油: " 
             << fuelLevel << "分钟" << endl;
        if (tower) {
            tower->processTakeoffRequest(this);
        }
    }
    
    void requestLanding() override {
        cout << "【私人飞机" << flightNumber << "】请求降落,燃油剩余: " 
             << fuelLevel << "分钟" << endl;
        if (tower) {
            tower->processLandingRequest(this);
        }
    }
    
    void receiveClearance(const string& clearance) override {
        cout << "【私人飞机" << flightNumber << "】收到指令: " << clearance << endl;
    }
    
    void reportPosition() override {
        cout << "【私人飞机" << flightNumber << "】当前位置: 高度5000米,速度500km/h" << endl;
    }
};

// ========== 具体同事类:军用机(高优先级) ==========
class MilitaryAircraft : public Aircraft {
public:
    MilitaryAircraft(const string& number, int fuel, int prio = 10)
        : Aircraft(number, AircraftType::MILITARY, fuel, prio) {}
    
    void requestTakeoff() override {
        cout << "【军用机" << flightNumber << "】请求紧急起飞,任务优先级最高!" << endl;
        if (tower) {
            tower->processTakeoffRequest(this);
        }
    }
    
    void requestLanding() override {
        cout << "【军用机" << flightNumber << "】请求紧急降落,需要立即清空跑道!" << endl;
        if (tower) {
            tower->processLandingRequest(this);
        }
    }
    
    void receiveClearance(const string& clearance) override {
        cout << "【军用机" << flightNumber << "】收到指令: " << clearance << " 立即执行!" << endl;
    }
    
    void reportPosition() override {
        cout << "【军用机" << flightNumber << "】当前位置: 高度12000米,速度1200km/h" << endl;
    }
};

// ========== 具体中介者:机场塔台 ==========
class AirportControlTower : public ControlTower {
private:
    map<string, Aircraft*> registeredAircraft;      // 所有注册的飞机
    queue<Aircraft*> takeoffQueue;                   // 起飞等待队列
    queue<Aircraft*> landingQueue;                    // 降落等待队列
    bool runwayOccupied;                              // 跑道是否被占用
    Aircraft* currentRunwayUser;                       // 当前使用跑道的飞机
    vector<string> flightLog;                          // 飞行日志
    
public:
    AirportControlTower() : runwayOccupied(false), currentRunwayUser(nullptr) {
        cout << "=== 机场塔台启动 ===" << endl;
    }
    
    void registerAircraft(Aircraft* aircraft) override {
        string number = aircraft->getFlightNumber();
        registeredAircraft[number] = aircraft;
        aircraft->setMediator(this);
        
        cout << "塔台: 飞机 " << number << " (" << aircraft->typeToString() 
             << ") 已注册到塔台,优先级: " << aircraft->getPriority() << endl;
        
        // 广播消息
        broadcastMessage("欢迎飞机 " + number + " 进入本场空域");
    }
    
    void unregisterAircraft(const string& flightNumber) override {
        auto it = registeredAircraft.find(flightNumber);
        if (it != registeredAircraft.end()) {
            cout << "塔台: 飞机 " << flightNumber << " 已离开本场空域" << endl;
            registeredAircraft.erase(it);
        }
    }
    
    void processTakeoffRequest(Aircraft* aircraft) override {
        cout << "塔台: 收到飞机 " << aircraft->getFlightNumber() << " 起飞请求" << endl;
        
        // 检查紧急情况
        if (aircraft->isEmergency()) {
            handleEmergency(aircraft);
            return;
        }
        
        // 军用机优先处理
        if (aircraft->getType() == AircraftType::MILITARY) {
            cout << "塔台: 军用机优先起飞,清空跑道!" << endl;
            if (runwayOccupied) {
                // 让当前使用跑道的飞机让出跑道
                cout << "塔台: 通知 " << currentRunwayUser->getFlightNumber() << " 让出跑道" << endl;
                currentRunwayUser->receiveClearance("立即让出跑道,军用机优先");
            }
            allocateRunway(aircraft);
            aircraft->receiveClearance("可以起飞,跑道已清空");
            return;
        }
        
        // 加入等待队列(按优先级排序)
        takeoffQueue.push(aircraft);
        cout << "塔台: 飞机 " << aircraft->getFlightNumber() << " 加入起飞队列,当前位置: " 
             << takeoffQueue.size() << endl;
        
        // 尝试处理下一个起飞请求
        processNextTakeoff();
    }
    
    void processLandingRequest(Aircraft* aircraft) override {
        cout << "塔台: 收到飞机 " << aircraft->getFlightNumber() << " 降落请求" << endl;
        
        // 检查紧急情况
        if (aircraft->isEmergency()) {
            handleEmergency(aircraft);
            return;
        }
        
        // 军用机优先处理
        if (aircraft->getType() == AircraftType::MILITARY) {
            cout << "塔台: 军用机优先降落,清空跑道!" << endl;
            if (runwayOccupied) {
                cout << "塔台: 通知 " << currentRunwayUser->getFlightNumber() << " 立即离开跑道" << endl;
                currentRunwayUser->receiveClearance("立即离开跑道,军用机紧急降落");
            }
            allocateRunway(aircraft);
            aircraft->receiveClearance("可以降落,跑道已清空");
            return;
        }
        
        // 加入等待队列(按优先级排序)
        landingQueue.push(aircraft);
        cout << "塔台: 飞机 " << aircraft->getFlightNumber() << " 加入降落队列,当前位置: " 
             << landingQueue.size() << endl;
        
        // 尝试处理下一个降落请求
        processNextLanding();
    }
    
    void processNextTakeoff() {
        if (runwayOccupied || takeoffQueue.empty()) return;
        
        // 按优先级重新排序队列(简单实现)
        vector<Aircraft*> temp;
        while (!takeoffQueue.empty()) {
            temp.push_back(takeoffQueue.front());
            takeoffQueue.pop();
        }
        
        sort(temp.begin(), temp.end(), [](Aircraft* a, Aircraft* b) {
            return a->getPriority() > b->getPriority();
        });
        
        for (auto* a : temp) {
            takeoffQueue.push(a);
        }
        
        // 获取最高优先级的飞机
        Aircraft* next = takeoffQueue.front();
        takeoffQueue.pop();
        
        if (allocateRunway(next)) {
            next->receiveClearance("可以起飞,跑道已分配");
        } else {
            // 如果跑道被占用,重新加入队列
            takeoffQueue.push(next);
        }
    }
    
    void processNextLanding() {
        if (runwayOccupied || landingQueue.empty()) return;
        
        // 按优先级和燃油量排序
        vector<Aircraft*> temp;
        while (!landingQueue.empty()) {
            temp.push_back(landingQueue.front());
            landingQueue.pop();
        }
        
        sort(temp.begin(), temp.end(), [](Aircraft* a, Aircraft* b) {
            if (a->getPriority() != b->getPriority()) {
                return a->getPriority() > b->getPriority();
            }
            return a->getFuelLevel() < b->getFuelLevel();  // 燃油少的优先
        });
        
        for (auto* a : temp) {
            landingQueue.push(a);
        }
        
        Aircraft* next = landingQueue.front();
        landingQueue.pop();
        
        if (allocateRunway(next)) {
            next->receiveClearance("可以降落,跑道已分配");
        } else {
            landingQueue.push(next);
        }
    }
    
    bool allocateRunway(Aircraft* aircraft) override {
        if (runwayOccupied) {
            cout << "塔台: 跑道被 " << currentRunwayUser->getFlightNumber() 
                 << " 占用,无法分配给 " << aircraft->getFlightNumber() << endl;
            return false;
        }
        
        runwayOccupied = true;
        currentRunwayUser = aircraft;
        cout << "塔台: 跑道已分配给飞机 " << aircraft->getFlightNumber() << endl;
        
        // 记录日志
        string logEntry = "跑道分配: " + aircraft->getFlightNumber() + 
                         " 时间: " + to_string(time(nullptr));
        flightLog.push_back(logEntry);
        
        return true;
    }
    
    void releaseRunway(Aircraft* aircraft) override {
        if (currentRunwayUser == aircraft) {
            runwayOccupied = false;
            currentRunwayUser = nullptr;
            cout << "塔台: 飞机 " << aircraft->getFlightNumber() << " 已释放跑道" << endl;
            
            // 尝试处理等待队列
            processNextTakeoff();
            processNextLanding();
        }
    }
    
    void handleEmergency(Aircraft* aircraft) override {
        cout << "\n!!! 紧急情况 !!! 飞机 " << aircraft->getFlightNumber() 
             << " 燃油不足,需要立即处理!" << endl;
        
        // 广播紧急情况
        broadcastMessage("紧急情况: 飞机 " + aircraft->getFlightNumber() + " 需要优先处理", aircraft);
        
        // 清空跑道
        if (runwayOccupied) {
            cout << "塔台: 命令 " << currentRunwayUser->getFlightNumber() << " 立即让出跑道" << endl;
            currentRunwayUser->receiveClearance("紧急情况,立即让出跑道");
            releaseRunway(currentRunwayUser);
        }
        
        // 优先分配跑道
        allocateRunway(aircraft);
        
        if (aircraft->getStatus() == FlightStatus::AIRBORNE) {
            aircraft->receiveClearance("紧急降落,可以立即降落");
        } else {
            aircraft->receiveClearance("紧急起飞,可以立即起飞");
        }
    }
    
    void broadcastMessage(const string& message, Aircraft* sender) override {
        cout << "\n【塔台广播】" << message << endl;
        
        for (auto& pair : registeredAircraft) {
            if (pair.second != sender) {
                pair.second->receiveClearance("【广播】" + message);
            }
        }
    }
    
    void broadcastMessage(const string& message, Aircraft* sender = nullptr) override {
        cout << "\n【塔台广播】" << message << endl;
        
        for (auto& pair : registeredAircraft) {
            if (pair.second != sender) {
                pair.second->receiveClearance("【广播】" + message);
            }
        }
    }
    
    void getStatus() const override {
        cout << "\n=== 塔台当前状态 ===" << endl;
        cout << "跑道占用: " << (runwayOccupied ? "是" : "否") << endl;
        if (runwayOccupied && currentRunwayUser) {
            cout << "当前使用跑道: " << currentRunwayUser->getFlightNumber() << endl;
        }
        
        cout << "\n注册飞机数量: " << registeredAircraft.size() << endl;
        cout << "起飞等待队列: " << takeoffQueue.size() << endl;
        cout << "降落等待队列: " << landingQueue.size() << endl;
        
        cout << "\n所有注册飞机:" << endl;
        for (const auto& pair : registeredAircraft) {
            cout << "  " << pair.first << " (" << pair.second->typeToString() 
                 << ") 状态: " << pair.second->statusToString(pair.second->getStatus())
                 << " 燃油: " << pair.second->getFuelLevel() << "分钟" << endl;
        }
        
        cout << "\n最近10条飞行日志:" << endl;
        int start = max(0, (int)flightLog.size() - 10);
        for (size_t i = start; i < flightLog.size(); ++i) {
            cout << "  " << flightLog[i] << endl;
        }
    }
};

// ========== 不使用中介者模式的直接通信(对比) ==========
class DirectAircraftCommunication {
public:
    // 问题:飞机之间需要直接通信,形成网状结构
    static void simulateDirectCommunication() {
        cout << "\n=== 不使用中介者模式:飞机直接通信 ===" << endl;
        
        // 创建飞机(但需要互相引用)
        class DirectAircraft {
        public:
            string id;
            vector<DirectAircraft*> otherAircraft;
            
            DirectAircraft(const string& name) : id(name) {}
            
            void addOther(DirectAircraft* other) {
                otherAircraft.push_back(other);
            }
            
            void requestTakeoff() {
                cout << "飞机 " << id << " 请求起飞" << endl;
                
                // 需要询问所有其他飞机的状态
                for (auto* plane : otherAircraft) {
                    if (plane->isTakingOff()) {
                        cout << "  发现 " << plane->id << " 正在起飞,等待..." << endl;
                        return;
                    }
                }
                
                // 还需要检查跑道状态、天气等
                cout << "  开始起飞程序" << endl;
            }
            
            bool isTakingOff() {
                return false;  // 简化实现
            }
        };
        
        // 创建飞机
        DirectAircraft plane1("CA123");
        DirectAircraft plane2("MU456");
        DirectAircraft plane3("CZ789");
        
        // 需要建立所有互相引用(网状结构)
        plane1.addOther(&plane2);
        plane1.addOther(&plane3);
        plane2.addOther(&plane1);
        plane2.addOther(&plane3);
        plane3.addOther(&plane1);
        plane3.addOther(&plane2);
        
        // 通信
        plane1.requestTakeoff();
        plane2.requestTakeoff();
    }
};

// ========== 客户端代码 ==========
int main() {
    cout << "=== 中介者模式演示:航空管制系统 ===\n" << endl;
    
    // 创建塔台(中介者)
    AirportControlTower tower;
    
    // 创建各种飞机(同事类)
    PassengerAircraft ca123("CA123", 120, 1);   // 客机,燃油120分钟
    PassengerAircraft mu456("MU456", 45, 1);    // 客机,燃油45分钟(即将紧急)
    CargoAircraft cz789("CZ789", 180, 2);       // 货机,燃油180分钟
    PrivateAircraft pv001("PV001", 60, 0);       // 私人飞机,燃油60分钟
    MilitaryAircraft mil001("MIL001", 200, 10);  // 军用机,高优先级
    
    // 注册到塔台
    cout << "\n【注册飞机到塔台】" << endl;
    tower.registerAircraft(&ca123);
    tower.registerAircraft(&mu456);
    tower.registerAircraft(&cz789);
    tower.registerAircraft(&pv001);
    tower.registerAircraft(&mil001);
    
    // 模拟飞行活动
    cout << "\n【模拟飞行活动】" << endl;
    
    // 飞机请求起飞
    ca123.setStatus(FlightStatus::WAITING_TAKEOFF);
    ca123.requestTakeoff();
    
    mu456.setStatus(FlightStatus::WAITING_TAKEOFF);
    mu456.requestTakeoff();
    
    cz789.setStatus(FlightStatus::WAITING_TAKEOFF);
    cz789.requestTakeoff();
    
    // 军用机紧急起飞(高优先级)
    mil001.setStatus(FlightStatus::WAITING_TAKEOFF);
    mil001.requestTakeoff();
    
    // 查看塔台状态
    tower.getStatus();
    
    // 模拟飞机起飞后释放跑道
    cout << "\n【飞机起飞完成】" << endl;
    ca123.setStatus(FlightStatus::AIRBORNE);
    tower.releaseRunway(&ca123);
    
    // 私人飞机请求起飞
    pv001.setStatus(FlightStatus::WAITING_TAKEOFF);
    pv001.requestTakeoff();
    
    // 模拟飞行一段时间
    cout << "\n【飞行一段时间后】" << endl;
    mu456.consumeFuel(20);  // 燃油只剩25分钟,变成紧急情况
    
    // 飞机请求降落
    mu456.setStatus(FlightStatus::APPROACHING);
    mu456.requestLanding();
    
    // 军用机请求降落
    mil001.setStatus(FlightStatus::APPROACHING);
    mil001.requestLanding();
    
    // 广播消息
    tower.broadcastMessage("注意:天气变化,有强气流");
    
    // 最终状态
    tower.getStatus();
    
    // 对比:不使用中介者模式
    DirectAircraftCommunication::simulateDirectCommunication();
    
    return 0;
}

7 总结

不使用中介者模式的坏处

如果不使用中介者模式,飞机之间需要直接通信:

方式1:网状结构通信

cpp 复制代码
// 问题:每架飞机需要知道所有其他飞机的状态
class BadAircraft {
private:
    string flightNumber;
    vector<BadAircraft*> allOtherAircraft;  // 需要维护所有其他飞机的引用
    bool takingOff;
    bool landing;
    int fuelLevel;
    
public:
    BadAircraft(const string& num) : flightNumber(num), takingOff(false), landing(false), fuelLevel(100) {}
    
    // 需要添加所有其他飞机的引用
    void addOtherAircraft(BadAircraft* other) {
        allOtherAircraft.push_back(other);
    }
    
    // 请求起飞时需要检查所有其他飞机
    void requestTakeoff() {
        cout << "飞机 " << flightNumber << " 请求起飞" << endl;
        
        // 检查是否有飞机正在起飞或降落
        for (auto* plane : allOtherAircraft) {
            if (plane->isTakingOff() || plane->isLanding()) {
                cout << "  发现 " << plane->flightNumber << " 正在起降,等待..." << endl;
                return;
            }
        }
        
        // 检查跑道状态(需要全局变量或额外通信)
        // 检查天气(需要额外信息)
        
        takingOff = true;
        cout << "  开始起飞" << endl;
    }
    
    // 问题:N架飞机需要N-1个引用
    // 问题:添加新飞机需要修改所有现有飞机的引用
    // 问题:通信逻辑分散在各个飞机中
    // 问题:难以实现优先级和紧急情况处理
};

问题:

  • 每架飞机需要知道所有其他飞机

  • 添加新飞机需要修改所有现有飞机

  • 通信逻辑分散,难以维护

  • 难以实现全局策略(如优先级、紧急处理)

  • 形成复杂的网状结构

方式2:全局变量和函数

cpp 复制代码
// 问题:使用全局变量管理状态
namespace GlobalAirTraffic {
    vector<string> takingOffAircraft;
    vector<string> landingAircraft;
    bool runwayOccupied = false;
    string currentRunwayUser;
    
    // 全局函数处理通信
    bool canTakeoff(const string& flightNumber) {
        if (runwayOccupied) {
            cout << "跑道被 " << currentRunwayUser << " 占用" << endl;
            return false;
        }
        
        if (!takingOffAircraft.empty()) {
            cout << "有飞机正在起飞" << endl;
            return false;
        }
        
        return true;
    }
    
    void requestTakeoff(const string& flightNumber) {
        if (canTakeoff(flightNumber)) {
            runwayOccupied = true;
            currentRunwayUser = flightNumber;
            takingOffAircraft.push_back(flightNumber);
            cout << flightNumber << " 开始起飞" << endl;
        }
    }
}

// 飞机类直接操作全局状态
class GlobalAircraft {
private:
    string flightNumber;
    
public:
    void takeoff() {
        GlobalAirTraffic::requestTakeoff(flightNumber);
    }
};

问题:

  • 全局变量导致命名空间污染

  • 难以控制访问权限

  • 难以进行单元测试

  • 线程安全问题

  • 缺乏面向对象的设计

方式3:集中式控制器但耦合度高

cpp 复制代码
// 问题:控制器与具体飞机类型耦合
class TightlyCoupledTower {
private:
    PassengerAircraft* passengerPlanes[10];
    CargoAircraft* cargoPlanes[10];
    int passengerCount;
    int cargoCount;
    
public:
    void addPassengerPlane(PassengerAircraft* plane) {
        passengerPlanes[passengerCount++] = plane;
    }
    
    void addCargoPlane(CargoAircraft* plane) {
        cargoPlanes[cargoCount++] = plane;
    }
    
    // 需要为每种飞机类型写不同的处理逻辑
    void processPassengerTakeoff(PassengerAircraft* plane) {
        // 特定于客机的处理
    }
    
    void processCargoTakeoff(CargoAircraft* plane) {
        // 特定于货机的处理
    }
    
    // 问题:添加新飞机类型需要修改控制器
    // 问题:代码重复
    // 问题:违反开闭原则
};

中介者模式的优势

  • 降低耦合:将多对多的关系简化为一对多的关系

  • 集中控制:交互逻辑集中在中介者中,便于管理

  • 提高可维护性:修改交互逻辑只需修改中介者

  • 提高复用性:同事类可以独立变化和复用

  • 简化协议:用一对多的交互替代多对多的交互

  • 符合开闭原则:可以创建新的中介者而不修改同事类

  • 职责清晰:同事类专注于自身业务,中介者负责协调

8 中介者模式的使用场景

  • 航空管制系统:塔台协调飞机起降

  • 聊天室系统:服务器作为中介者转发消息

  • GUI组件交互:对话框作为中介者协调组件

  • 工作流系统:工作流引擎协调任务执行

  • 微服务架构:API网关作为中介者

  • 消息队列系统:消息队列作为中介者

  • 交通控制系统:交通指挥中心协调车辆

中介者模式通过引入一个中介对象,将系统中对象之间的复杂交互关系进行封装,大大降低了系统的耦合度。它特别适合那些对象之间交互频繁、交互逻辑复杂的系统,能够让系统结构更加清晰,更易于维护和扩展。

相关推荐
JTCC2 小时前
Java 设计模式西游篇 - 第八回:适配器模式通万国 女儿国语言无障碍
python·设计模式·适配器模式
逆境不可逃2 小时前
【从零入门23种设计模式17】行为型之中介者模式
java·leetcode·microsoft·设计模式·职场和发展·中介者模式
Anurmy2 小时前
设计模式之抽象工厂
设计模式
蜜獾云3 小时前
设计模式之原型模式:以自己为原型,自己实现自己的对象拷贝逻辑
java·设计模式·原型模式
melonbo3 小时前
C++ 中用于模块间通信的设计模式
开发语言·c++·设计模式
蜜獾云3 小时前
设计模式之简单工厂模式(4):创建对象时不会暴露创建逻辑
java·设计模式·简单工厂模式
geovindu3 小时前
python: Builder Pattern
python·设计模式·建造者模式
蜜獾云3 小时前
设计模式之中介者模式:让互相调用的模块之间解耦合
microsoft·设计模式·中介者模式
absunique4 小时前
算法设计模式看编程思维的抽象能力的技术6
算法·设计模式