软件设计模式系列之十九——中介者模式
@
1 模式的定义
中介者模式是一种行为型设计模式,它用于降低对象之间的直接通信,通过引入一个中介者对象来管理对象之间的交互。这种模式有助于减少对象之间的耦合性,使系统更加可维护和扩展。中介者模式是Gang of Four(GoF)设计模式中的一员,旨在促进对象之间的松耦合关系,从而提高系统的灵活性。
2 举例说明
为了更好地理解中介者模式,让我们考虑一个简单的例子:一个多人在线聊天室应用程序。在这个应用程序中,有多个用户可以发送消息给其他用户,而不需要直接知道接收消息的用户是谁。中介者模式可以用来管理用户之间的消息传递。
在这个例子中,中介者充当聊天室的中心,所有用户都将消息发送到中介者,然后中介者负责将消息传递给适当的接收者。这样,用户之间不需要直接通信,而是通过中介者进行通信,从而降低了用户之间的耦合性。
3 结构
中介者模式的结构包括以下几个关键元素:
抽象中介者(Mediator):这是中介者模式的核心接口,它定义了中介者对象应该具备的方法,通常包括注册组件、发送消息等操作。
具体中介者(ConcreteMediator):具体中介者是抽象中介者的实现,它维护了对所有相关组件的引用,并负责协调它们之间的通信。
抽象组件(Colleague):抽象组件代表参与中介者模式的各个组件对象,它们通常具有一个指向中介者的引用,并定义了与其他组件对象通信的接口。
具体组件(ConcreteColleague):具体组件是抽象组件的实现,它们之间通过中介者来通信,而不是直接相互关联。
4 实现步骤
要实现中介者模式,您可以按照以下步骤进行:
定义抽象中介者接口:创建一个抽象中介者接口,其中包括方法来注册和发送消息。
创建具体中介者类:实现抽象中介者接口,管理所有具体组件对象的引用,并协调它们之间的通信。
定义抽象组件接口:创建一个抽象组件接口,其中包括方法来注册中介者和发送消息。
创建具体组件类:实现抽象组件接口,确保它们能够通过中介者对象进行通信。
在具体组件中使用中介者:在具体组件中使用中介者来发送消息,而不是直接与其他组件通信。
客户端代码:在客户端代码中创建中介者和组件对象,然后将组件对象注册到中介者中,以便它们可以相互通信。
5 代码实现
// 1. 定义抽象中介者接口
interface Mediator {
void register(Colleague colleague);
void send(String message, Colleague sender);
}
// 2. 创建具体中介者类
class ConcreteMediator implements Mediator {
private List<Colleague> colleagues = new ArrayList<>();
@Override
public void register(Colleague colleague) {
colleagues.add(colleague);
}
@Override
public void send(String message, Colleague sender) {
for (Colleague colleague : colleagues) {
if (colleague != sender) {
colleague.receive(message);
}
}
}
}
// 3. 定义抽象组件接口
interface Colleague {
void setMediator(Mediator mediator);
void send(String message);
void receive(String message);
}
// 4. 创建具体组件类
class ConcreteColleague implements Colleague {
private Mediator mediator;
private String name;
public ConcreteColleague(String name) {
this.name = name;
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
public void send(String message) {
mediator.send(message, this);
}
@Override
public void receive(String message) {
System.out.println(name + " received: " + message);
}
}
// 6. 客户端代码
public class Client {
public static void main(String[] args) {
Mediator mediator = new ConcreteMediator();
Colleague colleague1 = new ConcreteColleague("User1");
Colleague colleague2 = new ConcreteColleague("User2");
Colleague colleague3 = new ConcreteColleague("User3");
mediator.register(colleague1);
mediator.register(colleague2);
mediator.register(colleague3);
colleague1.setMediator(mediator);
colleague2.setMediator(mediator);
colleague3.setMediator(mediator);
colleague1.send("Hello, everyone!");
colleague2.send("Hi there!");
}
}
6 典型应用场景
中介者模式适用于以下场景:
多对多对象交互:当多个对象之间需要进行复杂的相互通信时,中介者模式可以帮助简化系统结构。
减少耦合性:当对象之间的直接耦合关系导致系统难以维护和扩展时,中介者模式可以降低对象之间的耦合度。
分布式系统:在分布式系统中,各个节点之间可能需要进行协同工作,中介者模式可以用于管理节点之间的通信。
7 优缺点
优点:
降低耦合性:中介者模式将对象之间的通信集中在一个中介者对象中,降低了对象之间的直接耦合,使系统更加灵活。
易于扩展:通过添加新的具体组件和中介者,可以轻松扩展系统,而无需修改现有代码。
集中控制:中介者模式允许将系统的控制逻辑集中在一个对象中,使系统更易于理解和维护。
缺点:
中介者对象复杂:随着系统的增长,中介者对象可能会变得复杂,包含大量的逻辑。
性能问题:由于中介者负责协调对象之间的通信,可能会导致性能问题,特别是在大规模系统中。
8 类似模式
与中介者模式类似的模式包括观察者模式和代理模式。虽然它们在某些方面具有相似性,但它们在用途和实现方式上有一些关键区别。
观察者模式(Observer Pattern):
观察者模式和中介者模式都处理对象之间的通信,但它们关注的侧重点不同。观察者模式是一对多的关系,其中一个主题对象(Subject)维护一组观察者(Observer),当主题对象的状态发生变化时,通知所有观察者。观察者之间通常不直接通信,而是通过主题对象。中介者模式关注多对多的对象通信,中介者充当对象之间的中心枢纽,协调它们的交互。观察者模式关注一对多的依赖关系,其中主题对象维护观察者列表,但观察者之间不直接通信,而是通过主题对象。
代理模式(Proxy Pattern):
代理模式和中介者模式都涉及到控制对象之间的访问和交互。代理充当目标对象的代表,可以控制对目标对象的访问。中介者模式关注多个对象之间的通信和协调,它引入一个中介者对象,使对象之间的关系更加松散。代理模式关注对单个对象的访问控制,代理对象通常封装了目标对象的功能,但并不协调多个对象之间的交互。
虽然这些模式都有助于降低对象之间的耦合性,但它们的关注点和应用场景略有不同。中介者模式用于协调多个对象之间的复杂通信,观察者模式用于建立一对多的依赖关系,代理模式用于控制对单个对象的访问,而发布-订阅模式用于发布和订阅事件或消息。选择哪种模式取决于具体的设计需求和问题背景。
9 小结
中介者模式是一种有助于管理多个对象之间通信的强大工具。通过引入中介者对象,它能够降低对象之间的耦合度,使系统更加灵活、易于扩展和维护。在设计软件系统时,考虑使用中介者模式来促进对象之间的松耦合关系,提高系统的可维护性和可扩展性。