【HeadFirst系列之HeadFirst设计模式】第19天之彻底搞懂中介者模式:解耦对象交互的终极利器!(含 Java 实战)

Scroll Down

深入解析中介者模式:解耦对象交互的最佳实践(含 Java 实战)

在软件开发中,随着系统复杂度的提升,对象之间的交互会变得错综复杂,难以维护。如果多个对象之间存在大量的直接引用,就会导致代码的耦合度过高,系统变得难以扩展和修改。

如何解决这个问题?——引入中介者模式(Mediator Pattern)! 🎯

本篇文章基于《Head First 设计模式》,带你深入理解中介者模式的核心思想、适用场景、优缺点,并剖析其在 JDK 和 Spring 框架中的应用,最后附上Java 代码实战


📌 1. 问题分析:为什么需要中介者模式?

1.1 传统对象交互的问题

假设我们在开发一个聊天室系统,多个用户可以相互发送消息。如果我们让每个用户对象都直接与其他用户通信,系统可能会变成这样👇:

class User {
    private String name;
    
    public User(String name) {
        this.name = name;
    }

    public void sendMessage(User receiver, String message) {
        System.out.println(this.name + " 发送消息给 " + receiver.getName() + ": " + message);
    }

    public String getName() {
        return name;
    }
}

缺陷:

  • 每个 User 都需要维护其他 User 的引用,导致 对象间耦合度过高
  • 随着 User 数量的增加,代码会变得极难维护
  • 无法灵活控制消息发送逻辑,比如添加日志、权限校验等。

💡 有没有更优雅的方式?—— 让一个“中介者”来管理用户的交互!


📌 2. 解决方案:引入中介者模式

2.1 什么是中介者模式?

中介者模式(Mediator Pattern) 定义了一个中介对象,用于封装一组对象之间的交互,使它们不需要直接引用彼此,而是通过中介者进行通信。

💡 核心思想

  • 降低对象之间的耦合度,使对象不需要直接交互,而是通过“中介”传递信息。
  • 提高系统的可扩展性,如果要修改交互逻辑,只需修改中介者,而不影响各个对象。
  • 简化对象间的交互逻辑,使代码更清晰、易维护。

📌 3. 代码实战:用中介者模式优化聊天室系统

3.1 设计思路

  • 创建一个 ChatMediator(中介者),用于管理 User 之间的消息传递。
  • User 不再直接相互通信,而是通过 ChatMediator 发送和接收消息

3.2 代码实现

🎯 定义中介者接口

interface ChatMediator {
    void sendMessage(String message, User user);
    void addUser(User user);
}

🎯 实现具体的中介者

import java.util.ArrayList;
import java.util.List;

class ChatMediatorImpl implements ChatMediator {
    private List<User> users = new ArrayList<>();

    @Override
    public void sendMessage(String message, User sender) {
        for (User user : users) {
            if (user != sender) { // 不能给自己发消息
                user.receiveMessage(message, sender);
            }
        }
    }

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

🎯 让 User 通过中介者进行通信

class User {
    private String name;
    private ChatMediator mediator;

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

    public void sendMessage(String message) {
        System.out.println(name + " 发送消息: " + message);
        mediator.sendMessage(message, this);
    }

    public void receiveMessage(String message, User sender) {
        System.out.println(name + " 收到来自 " + sender.getName() + " 的消息: " + message);
    }

    public String getName() {
        return name;
    }
}

🎯 测试代码

public class MediatorPatternDemo {
    public static void main(String[] args) {
        ChatMediator chatMediator = new ChatMediatorImpl();

        User alice = new User("Alice", chatMediator);
        User bob = new User("Bob", chatMediator);
        User charlie = new User("Charlie", chatMediator);

        chatMediator.addUser(alice);
        chatMediator.addUser(bob);
        chatMediator.addUser(charlie);

        alice.sendMessage("大家好!");
        bob.sendMessage("Hello Alice!");
    }
}

✅ 运行结果

Alice 发送消息: 大家好!
Bob 收到来自 Alice 的消息: 大家好!
Charlie 收到来自 Alice 的消息: 大家好!
Bob 发送消息: Hello Alice!
Alice 收到来自 Bob 的消息: Hello Alice!
Charlie 收到来自 Bob 的消息: Hello Alice!

🎯 代码优化点

  • User不再直接引用其他 User,解耦了用户之间的依赖关系。
  • 所有的消息传递都由 ChatMediator 负责,修改交互逻辑时只需修改 ChatMediatorImpl

📌 4. 中介者模式的优缺点

✅ 优点

  1. 降低对象耦合度,对象不再需要直接相互引用,提高代码的可维护性。
  2. 更容易扩展,只需修改中介者,不影响其他对象。
  3. 集中管理交互逻辑,增强代码的可读性和可维护性。

❌ 缺点

  1. 可能导致中介者变得过于复杂,如果交互逻辑过多,中介者可能成为**“上帝类”**(God Object)。
  2. 单点故障,如果中介者出现问题,整个系统可能受影响。

📌 5. 中介者模式在 JDK 和 Spring 框架中的应用

📌 JDK 中的应用

  1. java.util.Timer:Timer 负责管理多个定时任务,充当中介者角色。
  2. java.lang.reflect.Method.invoke():通过反射调用方法,而不需要直接访问对象的方法。

📌 Spring 框架中的应用

  1. Spring 的 DispatcherServlet(Spring MVC)
    • DispatcherServlet 充当中介者,负责将 HTTP 请求分发到不同的 Controller
  2. Spring 事件机制(ApplicationEvent & ApplicationListener)
    • ApplicationEventPublisher 充当中介者,解耦事件的发布者和监听者。

📌 6. 结语

🎯 中介者模式是解耦对象交互的一种有效方式,适用于需要集中管理多个对象交互的场景。

  • 通过引入中介者对象,降低对象间的直接依赖,让代码更易维护。
  • 在 JDK 和 Spring 框架中,中介者模式被广泛应用,如 DispatcherServlet、Spring 事件机制等。

💡 你在项目中有遇到类似的问题吗?欢迎留言交流! 🚀