中介者模式是一种行为型设计模式,核心思想是通过一个中介者对象来封装一组对象之间的交互,让这些对象不需要直接相互引用,从而降低对象之间的耦合程度,把原本复杂的网状交互结构转化为星型结构。当系统中多个对象之间存在频繁且复杂的交互逻辑时,对象交互集中化管理就成为了提升系统可维护性的重要手段。

中介者模式的核心结构
中介者模式主要包含以下几个核心角色:
- Mediator(抽象中介者):定义了各个同事对象之间交互的接口,通常包含多个事件处理方法,用于转发各个同事对象的请求。
- ConcreteMediator(具体中介者):实现抽象中介者接口,负责协调各个同事对象的交互逻辑,持有所有同事对象的引用,能够根据业务逻辑处理不同同事对象之间的通信。
- Colleague(抽象同事类):定义同事对象的公共接口,持有中介者对象的引用,通过中介者来和其他同事对象交互,而不是直接调用其他同事对象的方法。
- ConcreteColleague(具体同事类):实现抽象同事类的接口,当自身状态发生变化或者需要和其他同事对象交互时,通过持有的中介者对象发起请求,而不是直接和其他同事对象通信。
适合使用中介者模式的场景
1. 多个对象之间存在复杂的网状交互关系
当系统中多个对象之间需要频繁通信,且交互关系呈现复杂的网状结构时,每个对象都需要了解其他多个对象的状态和接口,会导致对象之间的耦合度极高,后续修改一个对象的逻辑可能会影响到多个关联对象。此时引入中介者模式,将所有的交互逻辑集中到中介者中,各个对象只需要和中介者交互,就能大幅降低耦合度。
2. 对象交互逻辑需要集中管控和复用
如果多个对象之间的交互逻辑需要在不同模块中复用,或者需要对交互过程进行统一的管控,比如添加日志、权限校验等操作,将交互逻辑集中到中介者中可以避免在每个对象中重复编写相同的交互代码,也方便后续对交互逻辑进行统一修改和扩展。
3. 需要降低系统维护成本,提升可扩展性
当系统后期需要新增或者删除交互对象时,如果使用直接交互的方式,需要修改所有和新增或删除对象相关的交互代码,维护成本很高。使用中介者模式后,只需要修改中介者的交互逻辑即可,各个同事对象的代码不需要做任何改动,大幅提升了系统的可扩展性。
对象交互集中化管理的优势
对象交互集中化管理是中介者模式的核心价值,主要优势体现在以下几个方面:
- 降低耦合度:对象之间不需要直接引用,只需要依赖中介者,减少了对象之间的依赖关系。
- 简化交互逻辑:把分散在各个对象中的交互逻辑统一放到中介者中,交互流程更加清晰,便于理解和调试。
- 提升可维护性:交互逻辑的修改只需要调整中介者,不需要修改各个同事对象,降低了修改带来的影响范围。
- 便于复用:通用的交互逻辑可以封装在中介者中,在不同的业务场景中复用,减少重复代码。
代码示例:聊天室场景实现中介者模式
以多人聊天室场景为例,每个用户不需要直接和其他用户通信,而是通过聊天室这个中介者来转发消息,符合中介者模式的应用场景。以下是Java语言的实现示例:
// 抽象中介者:聊天室接口
interface ChatRoomMediator {
void sendMessage(String message, User user);
void addUser(User user);
}
// 具体中介者:普通聊天室
class SimpleChatRoom implements ChatRoomMediator {
private List<User> users = new ArrayList<>();
@Override
public void addUser(User user) {
users.add(user);
System.out.println(user.getName() + " 加入聊天室");
}
@Override
public void sendMessage(String message, User user) {
// 遍历所有用户,给除了发送者之外的用户转发消息
for (User u : users) {
if (u != user) {
u.receiveMessage(message, user.getName());
}
}
}
}
// 抽象同事类:用户
abstract class User {
protected ChatRoomMediator mediator;
protected String name;
public User(ChatRoomMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public String getName() {
return name;
}
// 发送消息,通过中介者转发
public abstract void send(String message);
// 接收消息
public abstract void receiveMessage(String message, String senderName);
}
// 具体同事类:普通用户
class NormalUser extends User {
public NormalUser(ChatRoomMediator mediator, String name) {
super(mediator, name);
mediator.addUser(this);
}
@Override
public void send(String message) {
System.out.println(name + " 发送消息:" + message);
mediator.sendMessage(message, this);
}
@Override
public void receiveMessage(String message, String senderName) {
System.out.println(name + " 收到来自 " + senderName + " 的消息:" + message);
}
}
// 测试类
public class MediatorPatternTest {
public static void main(String[] args) {
// 创建聊天室中介者
ChatRoomMediator chatRoom = new SimpleChatRoom();
// 创建三个用户,自动加入聊天室
User user1 = new NormalUser(chatRoom, "张三");
User user2 = new NormalUser(chatRoom, "李四");
User user3 = new NormalUser(chatRoom, "王五");
// 用户1发送消息,其他用户会收到
user1.send("大家好,我是张三");
System.out.println("-------------------");
// 用户2发送消息
user2.send("你好张三,我是李四");
}
}
上述代码中,用户对象不需要知道其他用户的存在,只需要调用send方法,由聊天室中介者负责将消息转发给其他用户,实现了对象交互的集中化管理。如果后续需要新增消息过滤、消息存储等功能,只需要修改SimpleChatRoom的sendMessage方法即可,不需要修改每个用户类的代码。
使用中介者模式的注意事项
虽然中介者模式能降低对象耦合度,但需要注意不要将中介者变成万能的"上帝对象",如果系统中所有的交互逻辑都放到一个中介者中,会导致中介者代码过于臃肿,反而难以维护。此时可以考虑将中介者拆分为多个专门的中介者,分别处理不同模块的交互逻辑,保持中介者的职责单一。
另外,中介者模式适合交互关系复杂的场景,如果系统中对象之间的交互非常简单,只有少量的直接调用,就没有必要引入中介者模式,否则会增加系统的复杂度,反而得不偿失。