前言:

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

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

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

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

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

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

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

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

#include

#include

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 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 是中介者类。同事类通过中介者对象进行通信,而不是直接相互引用。这样可以减少对象之间的耦合性,并且使得对象之间的通信更加灵活。

二、结构图

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

Mediator(中介者):中介者是一个接口或抽象类,它定义了同事对象之间通信的方法。 ConcreteMediator(具体中介者):具体中介者是中介者的实现类,它包含了同事对象之间通信的具体逻辑。 Colleague(同事):同事是指需要进行通信的对象,它们通过中介者进行通信而不是直接相互引用。 ConcreteColleague(具体同事):具体同事是同事的实现类,它实现了同事接口,并且包含了需要与其他同事对象进行通信的具体逻辑。

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

+-----------------+ +-----------------+

| Colleague | | Colleague |

+-----------------+ +-----------------+

/|\ /|\

| |

| |

| |

+---------------------+ +---------------------+

| ConcreteColleague | | ConcreteColleague |

+---------------------+ +---------------------+

| |

| |

| |

+-----------------+ +-----------------+

| Mediator | | Mediator |

+-----------------+ +-----------------+

/|\ /|\

| |

| |

| |

+-----------------+ +-----------------+

| ConcreteMediator| | ConcreteMediator|

+-----------------+ +-----------------+

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

三、使用场景 

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

当一个系统中对象之间的交互比较复杂,导致对象之间的耦合度较高时,可以考虑使用中介者模式来简化对象之间的通信。 当一个对象需要与多个其他对象进行通信,但是直接与这些对象进行交互会导致系统过于复杂时,可以使用中介者模式来集中管理对象之间的通信。 当对象之间的交互需要进行扩展和修改时,中介者模式可以使得修改和扩展更加灵活,因为所有的通信逻辑都集中在中介者中。 当对象之间的通信导致循环依赖或者大量的逻辑交织在一起时,可以使用中介者模式来简化对象之间的关系,减少耦合度。 在图形界面应用程序中,中介者模式常常用于管理界面元素之间的交互,例如按钮、文本框、下拉框等组件之间的通信。

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

具体场景代码:

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

#include

#include

#include

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 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

#include

#include

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 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 函数中,创建了一个中介者对象和两个飞机对象,然后通过中介者对象进行起飞请求和许可的处理。

 

四、优缺点

中介者模式的优点包括:

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

中介者模式的缺点包括:

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

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

五、常见的10个面试题:

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

问题:什么是中介者模式? 答案解析:中介者模式是一种行为型设计模式,它通过引入一个中介者对象来封装一组对象之间的交互,从而降低对象之间的耦合度,使得对象之间的交互更加灵活和可维护。 问题:中介者模式的结构包括哪些角色? 答案解析:中介者模式包括中介者(Mediator)、具体中介者(ConcreteMediator)、同事(Colleague)和具体同事(ConcreteColleague)等角色。 问题:中介者模式的优点有哪些? 答案解析:中介者模式的优点包括降低对象之间的耦合度、简化对象之间的交互、提高系统的可维护性和可扩展性等。 问题:中介者模式的缺点有哪些? 答案解析:中介者模式可能会导致中介者对象过于复杂、性能问题等。 问题:中介者模式和观察者模式有何区别? 答案解析:中介者模式和观察者模式都是用于对象之间的通信,但中介者模式是通过中介者对象来进行通信,而观察者模式是通过观察者和被观察者之间的订阅-发布机制来进行通信。 问题:中介者模式在实际项目中的应用场景有哪些? 答案解析:中介者模式适用于系统中对象之间的交互较为复杂的场景,例如聊天室、飞机调度系统等。 问题:中介者模式和代理模式有何区别? 答案解析:中介者模式是用于对象之间的通信,而代理模式是用于控制对对象的访问。 问题:中介者模式和策略模式有何区别? 答案解析:中介者模式是用于对象之间的通信,而策略模式是用于封装可互换的算法。 问题:中介者模式如何解决对象之间的循环依赖问题? 答案解析:中介者模式通过引入中介者对象来解耦对象之间的直接依赖关系,从而避免循环依赖的问题。 问题:在中介者模式中,同事对象如何与中介者进行通信? 答案解析:同事对象通过中介者提供的接口来发送消息,中介者将消息传递给其他同事对象,从而实现对象之间的通信。

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: