Java 设计模式之中介者模式:解耦复杂交互的架构艺术(含 UML 图解)

简介: 中介者模式通过引入协调者解耦多个对象间的复杂交互,将网状依赖转化为星型结构。适用于聊天室、GUI事件系统等场景,提升可维护性与扩展性,但需防中介者过度膨胀。

Java 设计模式之中介者模式:解耦复杂交互的架构艺术(含 UML 图解)

在复杂系统中,当多个对象之间存在频繁交互时,很容易形成 "蜘蛛网" 般的依赖关系 —— 每个对象都需要知道其他多个对象的存在,导致代码耦合度极高,维护和扩展变得异常困难。中介者模式(Mediator Pattern)通过引入一个 "中间协调者",将多对多的交互简化为一对多,从而让系统结构更清晰、更灵活。

什么是中介者模式?

中介者模式属于行为型设计模式,它定义了一个中介对象,用于封装一系列对象之间的交互。通过中介者,各个对象不再需要显式地相互引用,而是通过中介者传递信息,从而降低对象间的耦合度,使它们可以独立地变化。

生活中最典型的中介者例子就是 "空中交通管制系统"—— 多架飞机之间不会直接通信,而是通过地面塔台(中介者)协调飞行路线,避免碰撞;还有 "聊天室",用户发送的消息通过聊天室转发给其他人,用户之间无需直接建立连接。

中介者模式的核心角色与 UML 类图

核心角色

中介者模式包含 4 个核心角色:

  1. 抽象中介者(Mediator):定义中介者与同事对象交互的接口,通常包含注册同事和转发消息的方法。
  2. 具体中介者(Concrete Mediator):实现抽象中介者接口,维护所有同事对象的引用,负责协调同事间的交互。
  3. 抽象同事类(Colleague):定义同事对象的接口,持有中介者的引用,提供与中介者通信的方法。
  4. 具体同事类(Concrete Colleague):实现抽象同事类,当需要与其他同事交互时,通过中介者完成。

UML 类图

+---------------------+       +----------------------+
|     Mediator        |<----->|     Colleague        |
+---------------------+       +----------------------+
| + register(Colleague)      | | - mediator: Mediator |
| + send(message, Colleague) | | + send(message)      |
+---------------------+       | + receive(message)    |
        ^                     +----------------------+
        |                            ^
        |                            |
+---------------------+       +----------------------+
| ConcreteMediator    |       | ConcreteColleagueA   |
+---------------------+       +----------------------+
| - colleagues: List  |       | + send(message)      |
| + register(Colleague)      | | + receive(message)    |
| + send(message, Colleague) | +----------------------+
+---------------------+               ...

                                   +----------------------+
                                   | ConcreteColleagueB   |
                                   +----------------------+
                                   | + send(message)      |
                                   | + receive(message)    |
                                   +----------------------+

在 UML 图中,中介者与同事是双向关联:中介者需要知道所有同事以便协调,同事也需要知道中介者以便发起交互。

代码实现:聊天室中介者

我们以 "多人聊天室" 为例实现中介者模式:用户(同事)发送的消息通过聊天室(中介者)转发给其他用户,用户之间无需直接通信。

1. 抽象中介者(聊天室接口)

/**
 * 抽象中介者:聊天室
 */
public interface ChatRoom {
   
    // 注册用户(添加同事)
    void register(User user);

    // 转发消息(中介者协调逻辑)
    void relayMessage(String message, User sender);
}

2. 具体中介者(具体聊天室)

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

/**
 * 具体中介者:微信群聊
 */
public class WeChatGroup implements ChatRoom {
   
    // 维护所有用户(同事)
    private List<User> users = new ArrayList<>();

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

    @Override
    public void relayMessage(String message, User sender) {
   
        // 遍历所有用户,将消息转发给除发送者外的其他人
        for (User user : users) {
   
            if (!user.equals(sender)) {
   
                user.receive(message, sender.getName());
            }
        }
    }
}

3. 抽象同事类(用户)

/**
 * 抽象同事类:用户
 */
public abstract class User {
   
    protected ChatRoom mediator; // 持有中介者引用
    protected String name;       // 用户名

    public User(ChatRoom 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 NormalUser extends User {
   
    public NormalUser(ChatRoom mediator, String name) {
   
        super(mediator, name);
    }

    @Override
    public void send(String message) {
   
        System.out.println(name + "发送消息:" + message);
        // 不直接调用其他用户,而是通过中介者转发
        mediator.relayMessage(message, this);
    }

    @Override
    public void receive(String message, String senderName) {
   
        System.out.println(name + "收到来自" + senderName + "的消息:" + message);
    }
}

5. 客户端使用

public class Client {
   
    public static void main(String[] args) {
   
        // 创建中介者:微信群聊
        ChatRoom weChatGroup = new WeChatGroup();

        // 创建同事:用户
        User alice = new NormalUser(weChatGroup, "Alice");
        User bob = new NormalUser(weChatGroup, "Bob");
        User charlie = new NormalUser(weChatGroup, "Charlie");

        // 用户加入群聊(注册到中介者)
        weChatGroup.register(alice);
        weChatGroup.register(bob);
        weChatGroup.register(charlie);

        // 发送消息
        alice.send("大家好,我是Alice!");
        System.out.println("---");
        bob.send("欢迎Alice加入!");
        System.out.println("---");
        charlie.send("今天有什么计划吗?");
    }
}

运行结果

Alice发送消息:大家好,我是Alice!
Bob收到来自Alice的消息:大家好,我是Alice!
Charlie收到来自Alice的消息:大家好,我是Alice!
---
Bob发送消息:欢迎Alice加入!
Alice收到来自Bob的消息:欢迎Alice加入!
Charlie收到来自Bob的消息:欢迎Alice加入!
---
Charlie发送消息:今天有什么计划吗?
Alice收到来自Charlie的消息:今天有什么计划吗?
Bob收到来自Charlie的消息:今天有什么计划吗?

从结果可见,用户之间完全通过WeChatGroup中介者交互,彼此无需持有对方的引用,实现了彻底解耦。

中介者模式的优缺点

优点

  1. 降低耦合度:将多对多的复杂关系简化为一对多,避免对象间的直接依赖。
  2. 集中控制交互:所有交互逻辑集中在中介者中,便于统一管理和维护。
  3. 简化对象设计:同事对象只需关注自身业务,无需了解其他对象的细节。
  4. 提高可扩展性:新增同事或修改交互规则时,只需调整中介者即可。

缺点

  1. 中介者可能过于臃肿:随着业务复杂度增加,中介者可能会集成过多逻辑,变得难以维护(称为 "中介者膨胀")。
  2. 单点故障风险:所有交互依赖中介者,一旦中介者出现问题,整个系统都会受影响。
  3. 可能违反开闭原则:如果新增同事类型需要修改中介者逻辑,则违反开闭原则。

适用场景

  1. 系统中对象之间存在复杂的网状交互关系(如多人协作系统、聊天工具)。
  2. 一个对象的行为依赖多个其他对象,且这些依赖关系经常变化。
  3. 希望通过一个中间层封装多个类的交互,避免类之间的直接引用(如 MVC 中的 Controller)。

实际应用案例

  1. GUI 框架的事件机制:如 Swing 中的EventDispatcher作为中介者,协调按钮、文本框等组件的事件交互。
  2. MVC 模式:Controller 作为 View 和 Model 之间的中介者,处理用户输入并更新模型。
  3. 微服务注册中心:如 Eureka/Nacos,服务之间通过注册中心发现和通信,而非直接交互。
  4. 消息队列:生产者和消费者通过队列中介通信,无需知道对方的存在。

总结

中介者模式通过引入 "第三方协调者",将对象间的复杂交互集中管理,有效解决了多对象依赖导致的耦合问题。它的核心价值在于解耦—— 将 "蜘蛛网" 式的依赖转化为 "星型" 结构,让系统更清晰、更灵活。

但需注意:中介者模式并非银弹,过度使用可能导致中介者本身成为 "大泥球"。实践中可结合单一职责原则,将复杂中介者拆分为多个小中介者,或通过工厂模式创建中介者,平衡灵活性和可维护性。

合理运用中介者模式,能让你的代码从混乱的依赖中解脱出来,真正实现 "高内聚,低耦合" 的设计目标。

目录
相关文章
|
3月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
410 0
|
3月前
|
设计模式 Java 程序员
Java 设计模式之工厂模式:对象创建的艺术(含 UML 图解)
本文详解Java工厂模式三大形态:简单工厂、工厂方法与抽象工厂,结合UML图解与代码实例,剖析其核心思想——“创建与使用分离”。通过计算器、日志系统、电子设备等案例,深入讲解各模式的实现原理、适用场景及优缺点,并对比选择策略。最后揭示工厂模式在JDK和主流框架中的实际应用,帮助开发者掌握对象创建的艺术,提升代码扩展性与可维护性。(238字)
425 5
|
3月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
455 2
|
3月前
|
人工智能 Java Nacos
基于 Spring AI Alibaba + Nacos 的分布式 Multi-Agent 构建指南
本文将针对 Spring AI Alibaba + Nacos 的分布式多智能体构建方案展开介绍,同时结合 Demo 说明快速开发方法与实际效果。
3157 68
|
3月前
|
人工智能 安全 Java
分布式 Multi Agent 安全高可用探索与实践
在人工智能加速发展的今天,AI Agent 正在成为推动“人工智能+”战略落地的核心引擎。无论是技术趋势还是政策导向,都预示着一场深刻的变革正在发生。如果你也在探索 Agent 的应用场景,欢迎关注 AgentScope 项目,或尝试使用阿里云 MSE + Higress + Nacos 构建属于你的 AI 原生应用。一起,走进智能体的新世界。
980 61
|
3月前
|
SQL 关系型数据库 MySQL
开源新发布|PolarDB-X v2.4.2开源生态适配升级
PolarDB-X v2.4.2开源发布,重点完善生态能力:新增客户端驱动、开源polardbx-proxy组件,支持读写分离与高可用;强化DDL变更、扩缩容等运维能力,并兼容MySQL主备复制及MCP AI生态。
开源新发布|PolarDB-X v2.4.2开源生态适配升级
|
3月前
|
人工智能
实训Agent创客:一键生成电商场景Agent
在阿里云百炼一键生成电商场景Agent,轻松帮您搞定商品展示图片、视频。快来参与活动任务吧!
511 2
|
3月前
|
人工智能 边缘计算 网络协议
阿里云渠道商:为什么阿里云服务器的网络延迟降低?
阿里云通过RDMA、神龙架构与全球加速网络,实现微秒级延迟和跨境访问提速4倍。覆盖AI训练、实时交互等场景,助力企业高效上云。技术领先,性能卓越,翼龙云提供专业支持与优惠助力。
|
3月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
378 8
|
人工智能 算法 数据管理
阿里云 OSS MetaQuery 全面升级——新增内容和语义的检索能力,助力 AI 应用快速落地
阿里云 OSS MetaQuery(数据索引)全新升级,支持基于内容和语义的智能检索,面向安防监控、智慧社区、智能零售等场景。企业可快速开启该能力,无需自建基础设施或优化模型,即可自动完成视频、图片、文档等非结构化数据的向量化与索引构建,基于成熟的精排算法和多路召回机制,有效提升检索准确率与召回率,轻松实现 RAG 多模态语义检索和 AI 应用,标志着 OSS 迈入 AI 原生数据管理新时代。
776 0

热门文章

最新文章