设计模式18-中介者模式(Mediator)
- 动机
- 定义
- 结构
- 类图解释:
- 交互方式:
- 左边流程图
- 右边流程图
- 联系中介者模式
- C++代码推导
- 优缺点
- 应用
- 总结
动机
- 在软件构建过程中,经常会出现多个对象互相关联交互的情况。他们之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。
- 在这种情况下,我们可使用一个中介对象来管理对象间的关联关系。避免相互的对象之间的紧耦合引用关系。从而更好地抵御外界的变化。
- 在复杂系统中,各个对象之间可能会有多种多样的直接相互依赖关系,导致系统变得难以理解和维护。中介者模式通过引入一个中介者对象,将对象之间的复杂交互逻辑进行集中管理,从而降低各个对象之间的耦合度,使系统更加易于维护和扩展。
定义
- 用一个中介对象来封装(封装变化)一系列的对象交互。终结者使各对象不需要显示的相互引用(编译时依赖变成运行时依赖),从而使其耦合松散也可以独立的改变他们之间的交互。–《设计模式》GOF
- 中介者模式定义了一个中介对象,该对象封装了对象之间的交互方式,使得对象之间不再需要显式地相互引用,从而使其耦合松散,且可以独立地改变它们之间的交互。
结构
这张图片展示的是设计模式中的一种经典结构——**中介者模式(Mediator Pattern)**的类图表示。中介者模式用于减少系统中对象之间的直接交互,通过引入一个中介者对象来协调它们之间的行为。这个模式特别适用于系统中对象之间存在大量复杂交互,并且这些交互导致代码难以理解和维护的场景。
类图解释:
-
Mediator(中介者):
- 是该结构的核心,它定义了一个接口,用于与各同事对象通信。
- 在图中,Mediator是一个抽象类或接口,具体的中介者行为由ConcreteMediator类实现。
- 通过与各个同事(Colleague)的交互,Mediator类能够控制或改变它们之间的交互方式。
-
Colleague(同事):
- 是系统中的其他对象,它们知道自己可以与其他同事对象交互,但具体交互是通过Mediator进行的。
- Colleague是一个抽象类或接口,表示所有同事的共有特征和行为。
- 在图中,ConcreteColleague1和ConcreteColleague2是Colleague的具体实现,它们分别代表不同的同事对象。
-
ConcreteMediator(具体中介者):
- 是Mediator接口的具体实现,包含了与同事对象交互的具体行为。
- 它管理同事之间的直接交互,降低同事之间的耦合度。
-
ConcreteColleague1 和 ConcreteColleague2(具体同事):
- 是Colleague接口的具体实现,代表了系统中的具体业务对象。
- 它们通过Mediator进行通信,而不是直接相互调用。
交互方式:
- 同事对象(如ConcreteColleague1和ConcreteColleague2)之间不直接通信,而是通过中介者对象(ConcreteMediator)进行通信。
- 中介者对象负责接收来自同事对象的请求,并根据需要转发给相应的同事对象。
- 这种结构有助于减少同事对象之间的依赖,使系统更加灵活和易于维护。
这张图片中展示的两个流程图与中介者模式(Mediator Pattern)的结构图有一定的相似之处,尤其是在如何组织节点和它们之间的交互方面,尽管它们本身并不直接代表中介者模式的实现。
左边流程图
左边的流程图形成了一个环形结构,每个节点(1,2,3,4,5)通过箭头顺序连接,形成一个闭环。这个结构可以类比于一个系统中的对象或任务,它们按照一定的顺序或逻辑相互依赖和执行。然而,在这个简单的环形流程图中,并没有直接体现中介者角色的存在。但我们可以想象,如果这个流程图中包含更多的复杂交互或需要控制节点之间交互的逻辑,那么引入一个中介者对象来管理这些交互将是有益的。
右边流程图
右边的流程图则更接近于中介者模式的一个简化表示。中心节点“M”可以视为中介者的角色,它连接并管理着周围的四个节点(1, 2, 3, 4,5)。这些节点之间的交互不是直接进行的,而是通过“M”节点来协调。中心节点“M”的存在减少了其他节点之间的直接耦合,使得系统更加灵活和可扩展。此外,“M”节点周围的三个小圆圈可能代表不同的状态、条件或处理逻辑,这些都可以由中介者根据需要进行管理和控制。
联系中介者模式
在中介者模式中,Mediator(中介者)对象负责协调各个Colleague(同事)对象之间的交互,从而降低它们之间的耦合度。这张图片中的右边流程图通过中心节点“M”来协调其他节点的交互,与中介者模式中的Mediator角色相呼应。虽然左边的流程图没有直接展示中介者,但它可以通过增加中介者角色来改进和优化节点之间的交互方式。
综上所述,这张图片中的两个流程图可以在一定程度上反映中介者模式的思想和结构,尤其是在如何通过引入中介者来管理对象之间的交互和降低耦合度方面。
C++代码推导
以下是一个中介者模式的C++代码示例:
中介者接口:
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
class Colleague;
class Mediator {
public:
virtual void notify(Colleague* sender, const std::string& event) = 0;
virtual void addColleague(Colleague* colleague) = 0;
virtual ~Mediator() = default;
};
同事类:
class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* mediator) : mediator(mediator) {}
virtual void send(const std::string& message) = 0;
virtual void receive(const std::string& message) = 0;
virtual ~Colleague() = default;
};
具体同事类:
class ConcreteColleague1 : public Colleague {
public:
ConcreteColleague1(Mediator* mediator) : Colleague(mediator) {}
void send(const std::string& message) override {
std::cout << "Colleague1 sends message: " << message << std::endl;
mediator->notify(this, message);
}
void receive(const std::string& message) override {
std::cout << "Colleague1 receives message: " << message << std::endl;
}
};
class ConcreteColleague2 : public Colleague {
public:
ConcreteColleague2(Mediator* mediator) : Colleague(mediator) {}
void send(const std::string& message) override {
std::cout << "Colleague2 sends message: " << message << std::endl;
mediator->notify(this, message);
}
void receive(const std::string& message) override {
std::cout << "Colleague2 receives message: " << message << std::endl;
}
};
具体中介者类:
class ConcreteMediator : public Mediator {
private:
std::vector<Colleague*> colleagues;
public:
void addColleague(Colleague* colleague) override {
colleagues.push_back(colleague);
}
void notify(Colleague* sender, const std::string& event) override {
for (auto colleague : colleagues) {
if (colleague != sender) {
colleague->receive(event);
}
}
}
};
客户端代码:
int main() {
ConcreteMediator* mediator = new ConcreteMediator();
ConcreteColleague1* colleague1 = new ConcreteColleague1(mediator);
ConcreteColleague2* colleague2 = new ConcreteColleague2(mediator);
mediator->addColleague(colleague1);
mediator->addColleague(colleague2);
colleague1->send("Hello, colleague2!");
colleague2->send("Hi, colleague1!");
delete colleague1;
delete colleague2;
delete mediator;
return 0;
}
优缺点
优点:
- 降低耦合:中介者模式通过引入中介者对象,使同事对象之间不再直接依赖,从而降低了对象之间的耦合度。
- 集中控制:中介者模式将交互逻辑集中在中介者中,使得修改和维护交互逻辑更加容易。
- 符合单一职责原则:中介者对象负责处理对象之间的交互,其他对象只关注自身的业务逻辑。
缺点:
- 中介者复杂化:随着系统中同事对象数量的增加,中介者对象可能会变得非常复杂,难以维护。
- 性能开销:所有的交互都通过中介者进行,可能会带来一定的性能开销。
应用
中介者模式在以下场景中应用较多:
- GUI系统:在复杂的GUI系统中,不同组件之间的交互可以通过中介者进行协调,避免组件之间的直接依赖。
- 网络通信:在网络通信中,可以通过中介者协调不同模块之间的数据传输和交互。
- 聊天室:在聊天室系统中,中介者可以负责转发消息、管理用户等
总结
- 中介者模式通过引入中介者对象,将对象之间的交互逻辑集中管理,从而降低对象之间的耦合度。尽管中介者模式可以有效地简化对象之间的交互,但在实际应用中需要注意中介者对象的复杂度和性能开销。在适当的场景下使用中介者模式,可以显著提高系统的可维护性和灵活性。
- 将多个对象间复杂的关联关系进行解耦。中介者模式将多个对象间的控制逻辑进行集中管理。变 “多个对象互相依赖” 为 “多个对象和一个中介者关联”。简化了系统的维护,抵御了可能的变化。
- 随着控制逻辑的复杂化,中介者具体对象的实现可能相当复杂。这时候可以对中介的对象进行分解处理。为了避免中介者对象变得过于庞大和复杂,可以将中介者对象进行分解处理,将不同的交互逻辑委派给多个小的中介者,从而简化主中介者的实现。
- 门面模式是解耦系统间单向的对象关联关系。中介者模式是解耦系统内各个对象之间(双向)的关联关系