中介者模式(手把手讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在软件开发中,设计模式是解决常见问题的通用方案。它们如同编程世界的“经验结晶”,帮助开发者高效地组织代码结构,提升系统的可维护性和扩展性。今天,我们将深入探讨 中介者模式(Mediator Pattern),这个旨在降低对象间耦合度的经典模式。通过理论讲解、比喻分析和代码示例,你将理解如何在实际项目中应用这一模式,为复杂系统注入简洁与优雅。


什么是中介者模式?

中介者模式 的核心思想是:通过引入一个“中间协调者”来管理多个对象之间的交互。它将原本分散的、直接的对象间通信,集中到一个统一的中介者(Mediator)中,从而减少对象间的直接依赖,使系统更易维护。

比喻:交通指挥系统

想象一个繁忙的十字路口,如果没有交通灯或交警,车辆和行人将直接相互协调,导致混乱。而交通灯作为“中介者”,通过统一的规则(红绿灯)管理所有参与者的行动,这就是中介者模式的直观体现。


中介者模式的核心思想

中介者模式通过以下原则实现解耦:

  1. 定义中介者接口:所有参与者通过统一接口与中介者通信。
  2. 抽象参与者角色:每个对象仅知道中介者,而不再直接依赖其他对象。
  3. 中介者协调交互:中介者维护参与者列表,并根据规则转发消息或执行操作。

关键角色解析

角色名称职责描述
Mediator定义中介者接口,声明参与者通知方法。
ConcreteMediator实现中介者接口,协调各参与者的行为。
Colleague抽象参与者类,持有中介者引用,并通过它发送消息。
ConcreteColleague具体参与者,实现特定业务逻辑,并通过中介者与其他对象交互。

中介者模式的适用场景

以下情况适合应用中介者模式:

  1. 对象间交互复杂:多个对象需要频繁通信,导致类间依赖关系网过于复杂。
  2. 需集中控制逻辑:希望将交互规则统一管理,避免分散在多个类中。
  3. 动态变化的系统:参与者数量或交互规则可能随需求变化,需灵活调整。

典型场景举例

  • 订单系统:订单、支付、库存模块需协调操作(如支付成功后更新库存)。
  • 聊天室功能:用户发送消息需经服务器转发,而非直接通信。
  • 窗体验证:表单组件间需联动验证(如密码和确认密码一致性)。

中介者模式的实现步骤

以下是实现中介者模式的通用流程:

1. 定义中介者接口

// Mediator.java
public interface Mediator {
    void send(String message, Colleague colleague);
}

2. 创建具体中介者

// ChatRoomMediator.java
public class ChatRoomMediator implements Mediator {
    private List<Colleague> colleagues = new ArrayList<>();

    @Override
    public void send(String message, Colleague colleague) {
        // 转发消息给所有其他参与者
        for (Colleague c : colleagues) {
            if (c != colleague) {
                c.receive(message, colleague);
            }
        }
    }

    public void addColleague(Colleague colleague) {
        colleagues.add(colleague);
    }
}

3. 抽象参与者类

// Colleague.java
public abstract class Colleague {
    protected Mediator mediator;

    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    public abstract void receive(String message, Colleague colleague);
}

4. 实现具体参与者

// User.java
public class User extends Colleague {
    private String name;

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

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

    public void send(String message) {
        mediator.send(message, this);
    }
}

实际案例:订单系统中的中介者模式

假设我们需要设计一个订单系统,涉及订单、支付和库存模块。传统方式下,三者直接耦合,修改支付逻辑时可能需要调整订单和库存代码。

未使用中介者模式的缺陷

// 订单类直接调用支付和库存
public class Order {
    public void confirm() {
        Payment payment = new Payment();
        payment.process();
        
        Inventory inventory = new Inventory();
        inventory.reduceStock();
    }
}

这种设计导致:

  • 高耦合:订单类直接依赖其他模块。
  • 难以扩展:若新增物流模块,需修改多个类。

使用中介者模式的改进

// Mediator.java
public interface BusinessMediator {
    void processOrder(Order order);
    void handlePayment(Payment payment);
    void updateInventory(Inventory inventory);
}

// BusinessMediatorImpl.java
public class BusinessMediatorImpl implements BusinessMediator {
    private PaymentService paymentService;
    private InventoryService inventoryService;

    @Override
    public void processOrder(Order order) {
        paymentService.process(order.getPayment());
        inventoryService.reduceStock(order.getProductId());
        // 可添加物流调用
    }
}

// Order.java
public class Order {
    private BusinessMediator mediator;

    public void confirm() {
        mediator.processOrder(this);
    }
}

通过中介者协调各模块,系统解耦且易于扩展。


中介者模式 vs 其他模式对比

与观察者模式的区别

  • 观察者模式:关注“一对多”通知,对象间无直接交互。
  • 中介者模式:管理对象间复杂交互,可能涉及多对多规则。

与策略模式的区别

  • 策略模式:通过算法切换实现行为变化。
  • 中介者模式:解决对象间通信的复杂性,而非算法选择。

中介者模式的常见误区

  1. 过度设计中介者:将所有交互塞入中介者,导致其成为“上帝对象”。
    • 解决方案:保持中介者职责单一,必要时拆分多个中介者。
  2. 忽略参与者抽象:直接让具体类持有中介者,而非通过抽象类。
    • 解决方案:通过抽象类强制参与者依赖接口,而非具体中介者。

中介者模式的进阶应用

1. 结合工厂模式创建中介者

// MediatorFactory.java
public class MediatorFactory {
    public static Mediator createMediator() {
        return new ChatRoomMediator();
    }
}

2. 在前端框架中的应用

在 React 或 Vue 中,状态管理库(如 Redux)可视为中介者模式的体现:组件通过统一的 store 通信,而非直接调用其他组件。


结论:解耦是设计的核心

中介者模式通过引入中间协调者,将复杂的对象间关系转化为“对象-中介者”的简单依赖,是解决高耦合系统的利器。无论是后端业务协调,还是前端组件交互,它都能帮助开发者构建更清晰、可维护的系统。

在实际开发中,建议根据需求灵活选择模式:当对象间交互规则复杂且频繁变化时,中介者模式将显著提升代码质量。记住,设计模式并非万能,但理解其思想,能让你在架构设计时多一份从容。


通过本文,希望你不仅掌握了中介者模式的实现方法,更能理解其背后的设计哲学——通过抽象协调,让系统在变化中保持优雅

最新发布