0%

中介者模式

中介者模式(Mediator Pattern):封装交互,解耦对象

中介者模式是行为型设计模式的一种,核心思想是通过一个中介对象封装多个对象(同事)之间的交互,使同事对象无需直接相互引用,从而降低耦合度,且可以独立地改变它们之间的交互方式。这种模式就像 “聊天室主持人”—— 多个用户(同事)通过主持人(中介者)传递信息,无需知道彼此的存在,所有交互由主持人协调,本质是 “集中管理交互,减少直接依赖”。

中介者模式的核心结构

中介者模式

中介者模式通过四个核心角色实现对象间的间接交互,职责分明且解耦效果显著:

中介者接口(Mediator)

  • 定义同事对象之间交互的接口,声明用于协调同事的方法(如changed(Colleague)—— 当同事状态改变时通知中介者)。
  • 示例:ChatMediator(聊天室中介者接口,声明sendMessage(String msg, User user)方法)。

具体中介者(ConcreteMediator)

  • 实现中介者接口,维护所有同事对象的引用,并实现具体的协调逻辑:当某个同事状态改变时,中介者负责通知其他相关同事做出响应。
  • 示例:ConcreteChatMediator(具体聊天室中介者,管理用户列表并转发消息)。

同事类抽象(Colleague)

  • 定义同事对象的抽象接口,持有中介者的引用(通过构造方法注入),提供与中介者交互的方法(如通知中介者自身状态改变)。
  • 示例:User(用户抽象类,包含send(String msg)receive(String msg)方法)。

具体同事类(ConcreteColleague)

  • 实现同事类抽象,代表具体的交互对象,当自身状态改变时,通过中介者通知其他同事,而不直接与其他同事交互。
  • 示例:ChatUser(具体用户,发送消息时通过中介者转发,接收中介者传递的消息)。

代码实现示例

以 “聊天室” 为例,展示中介者模式的实现:多个用户通过聊天室中介者发送和接收消息,用户之间无需直接关联,所有消息通过中介者转发。

1. 中介者接口与具体中介者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 1. 中介者接口:聊天室中介者
public interface ChatMediator {
// 发送消息:由中介者转发给其他用户
void sendMessage(String message, User sender);
// 添加用户到中介者管理
void addUser(User user);
}

// 2. 具体中介者:具体聊天室
public class ConcreteChatMediator implements ChatMediator {
private List<User> users = new ArrayList<>(); // 管理所有用户

@Override
public void addUser(User user) {
users.add(user);
}

@Override
public void sendMessage(String message, User sender) {
// 中介者转发消息:向除发送者外的所有用户传递消息
for (User user : users) {
if (user != sender) { // 不发给自己
user.receive(message, sender.getName());
}
}
}
}

2. 同事类抽象与具体同事类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// 3. 同事类抽象:用户
public abstract class User {
protected ChatMediator mediator; // 持有中介者引用
protected String name; // 用户名

public User(ChatMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}

public String getName() {
return name;
}

// 发送消息:通过中介者转发
public abstract void send(String message);

// 接收消息:由中介者传递
public abstract void receive(String message, String senderName);
}

// 4. 具体同事类:聊天室用户
public class ChatUser extends User {
public ChatUser(ChatMediator mediator, String name) {
super(mediator, name);
}

@Override
public void send(String message) {
System.out.printf("[%s]发送消息:%s%n", name, message);
// 不直接发给其他用户,而是通过中介者
mediator.sendMessage(message, this);
}

@Override
public void receive(String message, String senderName) {
System.out.printf("[%s]收到来自[%s]的消息:%s%n", name, senderName, message);
}
}

3. 客户端使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MediatorDemo {
public static void main(String[] args) {
// 创建中介者(聊天室)
ChatMediator mediator = new ConcreteChatMediator();

// 创建同事(用户)并加入聊天室
User alice = new ChatUser(mediator, "Alice");
User bob = new ChatUser(mediator, "Bob");
User charlie = new ChatUser(mediator, "Charlie");
mediator.addUser(alice);
mediator.addUser(bob);
mediator.addUser(charlie);

// 用户发送消息(通过中介者转发)
alice.send("大家好!");
// 输出:
// [Alice]发送消息:大家好!
// [Bob]收到来自[Alice]的消息:大家好!
// [Charlie]收到来自[Alice]的消息:大家好!

bob.send("Alice你好!");
// 输出:
// [Bob]发送消息:Alice你好!
// [Alice]收到来自[Bob]的消息:Alice你好!
// [Charlie]收到来自[Bob]的消息:Alice你好!
}
}

中介者模式的核心优势

  1. 减少对象间的直接耦合
    同事对象之间无需知道彼此的存在,所有交互通过中介者完成,将多对多的复杂依赖简化为一对多(同事→中介者),降低了系统的复杂度。
  2. 集中管理交互逻辑
    原本分散在多个同事类中的交互逻辑被集中到中介者中,便于统一维护和修改(如修改消息转发规则只需修改中介者,无需改动所有用户类)。
  3. 提高对象的复用性
    同事对象因不依赖其他同事,可独立复用(如一个用户可加入多个聊天室,只需关联不同的中介者)。
  4. 简化对象通信
    新同事加入或移除时,只需在中介者中添加或删除引用,无需修改其他同事的代码,符合开闭原则。

适用场景

  1. 对象间交互复杂,形成网状依赖
    当多个对象之间存在频繁的相互调用(如表单中的多个输入框、按钮、下拉框相互影响),导致类图呈网状结构时,中介者模式可将网状依赖转为星型依赖(所有对象依赖中介者)。
  2. 希望集中管理对象交互
    如:
    • 聊天室 / 消息队列:用户通过中介者(服务器)收发消息,避免点对点通信。
    • GUI 组件交互:如表单验证(输入框内容变化时,按钮状态和提示信息通过中介者联动)。
    • 航空管制系统:多个飞机的起降调度通过管制中心(中介者)协调,避免飞机直接通信。
  3. 需要简化对象引用
    当一个对象需要引用多个其他对象才能完成操作(导致代码臃肿)时,可通过中介者统一处理这些引用。

优缺点分析

优点

  • 解耦效果显著:消除对象间的直接依赖,降低系统维护难度。
  • 交互逻辑集中:便于监控和修改对象间的交互规则。
  • 扩展性好:新增同事或修改交互只需扩展中介者,对现有同事影响小。

缺点

  • 中介者可能过度臃肿:若同事间交互复杂,中介者会集中大量逻辑,导致其变得庞大且难以维护(称为 “中介者膨胀” 问题)。
  • 中介者成为单点故障:中介者的异常会影响所有同事的交互,需确保其中介者的稳定性。

经典应用案例

  1. MVC 模式中的 Controller
    MVC 模式中,Controller 扮演了中介者的角色:View(视图)和 Model(模型)不直接交互,而是通过 Controller 协调(View 的用户操作通知 Controller,Controller 更新 Model,Model 变化通过 Controller 通知 View 刷新)。
  2. 消息中间件(如 RabbitMQ、Kafka)
    消息生产者和消费者通过消息队列(中介者)传递消息,无需知道彼此的地址,队列负责消息的存储和转发,是分布式系统中的中介者模式实现。
  3. GUI 框架的事件总线(EventBus)
    如 Google 的Guava EventBus:组件通过总线发送和接收事件,无需直接引用,总线作为中介者管理事件的订阅和发布。
  4. 聊天室 / 即时通讯系统
    如微信的群聊功能:群成员发送的消息通过服务器(中介者)转发给其他成员,成员之间无需建立直接连接。

总结

中介者模式通过引入中介者对象,将多对象间的复杂交互集中管理,有效降低了系统的耦合度。其核心价值在于将 “网状依赖” 转化为 “星型依赖”,使对象间的通信更清晰、更易于维护。但需注意避免中介者过度集中逻辑导致的 “膨胀问题”,可通过拆分中介者(如按功能划分多个子中介者)缓解

欢迎关注我的其它发布渠道