【设计模式】深入理解中介者模式,解耦对象之间的复杂交互,实现用户之间的消息传递,优化飞机之间的航线协调,构建高效的系统交互方式

前言:

中介者模式是一种行为型设计模式,其核心思想是通过引入一个中介者对象来封装一组对象之间的交互。这种模式可以降低对象之间的耦合度,使得对象之间的交互更加灵活和可维护。

在现实世界中,我们经常会遇到需要协调多个对象之间交互的场景,例如聊天室中的用户之间的消息交互、飞机调度系统中飞机之间的航线调度等。这些场景中,如果对象之间的交互过于复杂,直接的交互方式可能会导致系统难以维护和扩展。而中介者模式的出现正是为了解决这些问题。

通过中介者模式,我们可以将对象之间的交互逻辑集中到中介者对象中,从而降低对象之间的直接依赖关系。这样一来,当系统需要进行修改或扩展时,只需要修改中介者对象而不影响其他对象,使得系统更加灵活和可维护。

总的来说,中介者模式可以帮助我们简化对象之间的交互,降低系统的复杂度,提高系统的可维护性和可扩展性。在实际开发中,合理地运用中介者模式可以使系统更加健壮和灵活。

一、原理及C++示例代码:

中介者模式是一种行为设计模式,它允许对象之间通过一个中介者对象进行通信,而不是直接相互引用。这可以减少对象之间的耦合性,并且使得对象之间的通信更加灵活。

在中介者模式中,中介者对象通常包含了对象之间通信所需的逻辑,并且可以处理对象之间的交互。对象之间的通信通常是通过中介者对象进行的,而不是直接相互引用。

下面是一个简单的C++示例代码,演示了中介者模式的实现:

#include <iostream>
#include <string>

class Mediator;

class Colleague {
public:
    virtual void sendMessage(const std::string& message) = 0;
    virtual void receiveMessage(const std::string& message) = 0;
    virtual void setMediator(Mediator* mediator) = 0;
};

class ConcreteColleague : public Colleague {
public:
    void sendMessage(const std::string& message) override {
        mediator_->sendMessage(message, this);
    }

    void receiveMessage(const std::string& message) override {
        std::cout << "Received message: " << message << std::endl;
    }

    void setMediator(Mediator* mediator) override {
        mediator_ = mediator;
    }

private:
    Mediator* mediator_;
};

class Mediator {
public:
    void addColleague(Colleague* colleague) {
        colleagues_.push_back(colleague);
    }

    void sendMessage(const std::string& message, Colleague* sender) {
        for (auto colleague : colleagues_) {
            if (colleague != sender) {
                colleague->receiveMessage(message);
            }
        }
    }

private:
    std::vector<Colleague*> colleagues_;
};

int main() {
    Mediator mediator;
    ConcreteColleague colleague1;
    ConcreteColleague colleague2;

    colleague1.setMediator(&mediator);
    colleague2.setMediator(&mediator);

    mediator.addColleague(&colleague1);
    mediator.addColleague(&colleague2);

    colleague1.sendMessage("Hello, colleague2!");
    colleague2.sendMessage("Hi, colleague1!");

    return 0;
}

在上面的示例中,Colleague 是同事类的抽象基类,ConcreteColleague 是具体的同事类,Mediator 是中介者类。同事类通过中介者对象进行通信,而不是直接相互引用。这样可以减少对象之间的耦合性,并且使得对象之间的通信更加灵活。

二、结构图

中介者模式的结构图包括以下几个要素:

  1. Mediator(中介者):中介者是一个接口或抽象类,它定义了同事对象之间通信的方法。

  2. ConcreteMediator(具体中介者):具体中介者是中介者的实现类,它包含了同事对象之间通信的具体逻辑。

  3. Colleague(同事):同事是指需要进行通信的对象,它们通过中介者进行通信而不是直接相互引用。

  4. ConcreteColleague(具体同事):具体同事是同事的实现类,它实现了同事接口,并且包含了需要与其他同事对象进行通信的具体逻辑。

下面是中介者模式的结构图示例:

  +-----------------+          +-----------------+
  |   Colleague    |          |   Colleague    |
  +-----------------+          +-----------------+
         /|\                         /|\
          |                           |
          |                           |
          |                           |
+---------------------+   +---------------------+
| ConcreteColleague  |   | ConcreteColleague  |
+---------------------+   +---------------------+
          |                           |
          |                           |
          |                           |
  +-----------------+          +-----------------+
  |    Mediator     |          |    Mediator     |
  +-----------------+          +-----------------+
         /|\                         /|\
          |                           |
          |                           |
          |                           |
  +-----------------+          +-----------------+
  | ConcreteMediator|          | ConcreteMediator|
  +-----------------+          +-----------------+

在上面的结构图中,Colleague 表示同事的接口或抽象类,ConcreteColleague 表示具体的同事类;Mediator 表示中介者的接口或抽象类,ConcreteMediator 表示具体的中介者类。同事对象通过中介者对象进行通信,而不是直接相互引用,这样可以减少对象之间的耦合性。

三、使用场景 

中介者模式通常适用于以下场景:

  1. 当一个系统中对象之间的交互比较复杂,导致对象之间的耦合度较高时,可以考虑使用中介者模式来简化对象之间的通信。

  2. 当一个对象需要与多个其他对象进行通信,但是直接与这些对象进行交互会导致系统过于复杂时,可以使用中介者模式来集中管理对象之间的通信。

  3. 当对象之间的交互需要进行扩展和修改时,中介者模式可以使得修改和扩展更加灵活,因为所有的通信逻辑都集中在中介者中。

  4. 当对象之间的通信导致循环依赖或者大量的逻辑交织在一起时,可以使用中介者模式来简化对象之间的关系,减少耦合度。

  5. 在图形界面应用程序中,中介者模式常常用于管理界面元素之间的交互,例如按钮、文本框、下拉框等组件之间的通信。

总之,中介者模式适用于需要简化对象之间通信关系、降低耦合度、集中管理对象交互逻辑的情况。

具体场景代码:

假设有一个简单的聊天室程序,其中多个用户(Colleague)可以通过中介者(Mediator)进行消息的发送和接收。

#include <iostream>
#include <string>
#include <vector>

class Mediator;

// 抽象同事类
class Colleague {
public:
    virtual void sendMessage(const std::string& message) = 0;
    virtual void receiveMessage(const std::string& message) = 0;
    virtual void setMediator(Mediator* mediator) = 0;
};

// 具体同事类
class ConcreteColleague : public Colleague {
public:
    ConcreteColleague(const std::string& name) : name(name), mediator(nullptr) {}

    void sendMessage(const std::string& message) override {
        mediator->sendMessage(this, message);
    }

    void receiveMessage(const std::string& message) override {
        std::cout << name << " received: " << message << std::endl;
    }

    void setMediator(Mediator* mediator) override {
        this->mediator = mediator;
    }

private:
    std::string name;
    Mediator* mediator;
};

// 抽象中介者类
class Mediator {
public:
    virtual void sendMessage(Colleague* colleague, const std::string& message) = 0;
    virtual void addColleague(Colleague* colleague) = 0;
};

// 具体中介者类
class ConcreteMediator : public Mediator {
public:
    void sendMessage(Colleague* colleague, const std::string& message) override {
        for (auto c : colleagues) {
            if (c != colleague) {
                c->receiveMessage(message);
            }
        }
    }

    void addColleague(Colleague* colleague) override {
        colleagues.push_back(colleague);
    }

private:
    std::vector<Colleague*> colleagues;
};

int main() {
    ConcreteMediator mediator;
    ConcreteColleague colleague1("Alice");
    ConcreteColleague colleague2("Bob");

    colleague1.setMediator(&mediator);
    colleague2.setMediator(&mediator);

    mediator.addColleague(&colleague1);
    mediator.addColleague(&colleague2);

    colleague1.sendMessage("Hello, Bob!");
    colleague2.sendMessage("Hi, Alice!");

    return 0;
}

在上面的示例中,ConcreteColleague 表示具体的同事类,ConcreteMediator 表示具体的中介者类。同事对象通过中介者对象进行通信,而不是直接相互引用。在 main 函数中,创建了一个中介者对象和两个同事对象,然后通过中介者对象进行消息的发送和接收。

假设有一个简单的飞机交通管制系统,多架飞机(Colleague)需要通过中介者(Mediator)进行通信和协调飞行。

#include <iostream>
#include <string>
#include <vector>

class Mediator;

// 抽象飞机类
class Aircraft {
public:
    virtual void requestTakeoff() = 0;
    virtual void receivePermission() = 0;
    virtual void setMediator(Mediator* mediator) = 0;
};

// 具体飞机类
class ConcreteAircraft : public Aircraft {
public:
    ConcreteAircraft(const std::string& name) : name(name), mediator(nullptr) {}

    void requestTakeoff() override {
        mediator->requestTakeoff(this);
    }

    void receivePermission() override {
        std::cout << name << " has received permission to take off." << std::endl;
    }

    void setMediator(Mediator* mediator) override {
        this->mediator = mediator;
    }

private:
    std::string name;
    Mediator* mediator;
};

// 抽象中介者类
class Mediator {
public:
    virtual void requestTakeoff(Aircraft* aircraft) = 0;
    virtual void grantPermission() = 0;
};

// 具体中介者类
class AirTrafficControl : public Mediator {
public:
    void requestTakeoff(Aircraft* aircraft) override {
        pendingAircraft.push_back(aircraft);
        grantPermission();
    }

    void grantPermission() override {
        if (!pendingAircraft.empty()) {
            pendingAircraft.front()->receivePermission();
            pendingAircraft.erase(pendingAircraft.begin());
        }
    }

private:
    std::vector<Aircraft*> pendingAircraft;
};

int main() {
    AirTrafficControl mediator;
    ConcreteAircraft aircraft1("Flight 001");
    ConcreteAircraft aircraft2("Flight 002");

    aircraft1.setMediator(&mediator);
    aircraft2.setMediator(&mediator);

    aircraft1.requestTakeoff();
    aircraft2.requestTakeoff();

    return 0;
}

在上面的示例中,ConcreteAircraft 表示具体的飞机类,AirTrafficControl 表示具体的中介者类。飞机对象通过中介者对象进行请求起飞,中介者会进行协调并向飞机发放起飞许可。在 main 函数中,创建了一个中介者对象和两个飞机对象,然后通过中介者对象进行起飞请求和许可的处理。

 

四、优缺点

中介者模式的优点包括:

  1. 减少了对象之间的直接通信,将复杂的交互逻辑集中在中介者中,降低了对象之间的耦合度,使得系统更易于维护和扩展。
  2. 可以简化对象之间的交互,因为对象无需了解其他对象的详细信息,只需要与中介者进行通信即可。
  3. 提高了系统的可复用性和灵活性,因为中介者模式将交互逻辑集中在一个地方,当需要修改或扩展交互逻辑时,只需修改中介者而无需修改各个同事类。

中介者模式的缺点包括:

  1. 中介者可能会变得过于复杂,因为所有的交互逻辑都集中在中介者中,可能会导致中介者变得庞大和难以维护。
  2. 中介者模式可能会导致性能问题,因为所有的通信都需要经过中介者进行处理,可能会增加系统的负担。

在设计中介者模式时,需要权衡对象之间的交互复杂性和中介者的复杂性,以及对性能的影响,从而选择合适的设计方案。

五、常见的10个面试题:

当面试官提出关于中介者模式的问题时,你可能会遇到以下一些常见的问题,以及相应的答案解析:

  1. 问题:什么是中介者模式? 答案解析:中介者模式是一种行为型设计模式,它通过引入一个中介者对象来封装一组对象之间的交互,从而降低对象之间的耦合度,使得对象之间的交互更加灵活和可维护。

  2. 问题:中介者模式的结构包括哪些角色? 答案解析:中介者模式包括中介者(Mediator)、具体中介者(ConcreteMediator)、同事(Colleague)和具体同事(ConcreteColleague)等角色。

  3. 问题:中介者模式的优点有哪些? 答案解析:中介者模式的优点包括降低对象之间的耦合度、简化对象之间的交互、提高系统的可维护性和可扩展性等。

  4. 问题:中介者模式的缺点有哪些? 答案解析:中介者模式可能会导致中介者对象过于复杂、性能问题等。

  5. 问题:中介者模式和观察者模式有何区别? 答案解析:中介者模式和观察者模式都是用于对象之间的通信,但中介者模式是通过中介者对象来进行通信,而观察者模式是通过观察者和被观察者之间的订阅-发布机制来进行通信。

  6. 问题:中介者模式在实际项目中的应用场景有哪些? 答案解析:中介者模式适用于系统中对象之间的交互较为复杂的场景,例如聊天室、飞机调度系统等。

  7. 问题:中介者模式和代理模式有何区别? 答案解析:中介者模式是用于对象之间的通信,而代理模式是用于控制对对象的访问。

  8. 问题:中介者模式和策略模式有何区别? 答案解析:中介者模式是用于对象之间的通信,而策略模式是用于封装可互换的算法。

  9. 问题:中介者模式如何解决对象之间的循环依赖问题? 答案解析:中介者模式通过引入中介者对象来解耦对象之间的直接依赖关系,从而避免循环依赖的问题。

  10. 问题:在中介者模式中,同事对象如何与中介者进行通信? 答案解析:同事对象通过中介者提供的接口来发送消息,中介者将消息传递给其他同事对象,从而实现对象之间的通信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五木大大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值