【设计模式】【行为型模式】中介者模式(Mediator)

简介: 一、入门 什么是中介者模式? 中介者模式(Mediator Pattern)是一种行为设计模式,旨在减少对象之间的直接依赖,通过引入一个中介者对象来协调多个对象之间的交互。这种模式特别适用于对象间存在

👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD

🔥 2025本人正在沉淀中... 博客更新速度++

👍 欢迎点赞、收藏、关注,跟上我的更新节奏

🎵 当你的天空突然下了大雨,那是我在为你炸乌云

一、入门

什么是中介者模式?

中介者模式(Mediator Pattern)是一种行为设计模式,旨在减少对象之间的直接依赖,通过引入一个中介者对象来协调多个对象之间的交互。这种模式特别适用于对象间存在复杂交互的场景,能够简化系统结构并降低耦合。
中介者模式的核心是封装对象间的交互,避免对象直接相互调用,而是通过中介者进行通信。这样,对象只需与中介者交互,而不需要知道其他对象的存在。

为什么要中介者模式?

假设有一个聊天室系统,多个用户(User)之间可以直接发送消息。如果没有中介者模式,用户之间会直接相互依赖:

class User {
   
    private String name;

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

    public void sendMessage(String message, User receiver) {
   
        System.out.println(name + " sends: " + message);
        receiver.receiveMessage(message, this);
    }

    public void receiveMessage(String message, User sender) {
   
        System.out.println(name + " received from " + sender.name + ": " + message);
    }
}

public class ChatRoomWithoutMediator {
   
    public static void main(String[] args) {
   
        User alice = new User("Alice");
        User bob = new User("Bob");
        User charlie = new User("Charlie");

        alice.sendMessage("Hi Bob!", bob);
        bob.sendMessage("Hello Alice!", alice);
        charlie.sendMessage("Hey everyone!", alice); // 需要手动发送给每个人
    }
}

在没有中介者模式的情况下,对象之间通常会直接相互调用和依赖,导致以下问题:

  1. 对象间耦合度高:
    • 每个对象都需要知道其他对象的存在,并直接调用它们的方法。
    • 如果对象间的关系复杂,依赖会变得混乱,难以维护。
  2. 交互逻辑分散:
    • 对象间的交互逻辑分散在各个对象中,导致代码重复且难以管理。
    • 修改一个对象的逻辑可能会影响其他多个对象。
  3. 系统难以扩展:
    • 新增或修改对象时,可能需要修改多个相关对象的代码。
    • 系统的可扩展性和灵活性较差。
  4. 难以理解和维护:
    • 对象间的直接依赖关系使得代码难以理解,尤其是在对象数量多、交互复杂的情况下。

怎么实现中介者模式?

在中介者模式中有如下角色:

  • Mediator(中介者接口):定义对象间通信的接口。
  • ConcreteMediator(具体中介者):实现中介者接口,协调各对象间的交互。
  • Colleague(同事类):定义各个对象的接口,每个同事类都知道中介者,并通过中介者与其他对象通信。
  • ConcreteColleague(具体同事类):实现同事类接口,与其他对象通过中介者交互。

【案例】聊天室 - 改
image.png

Mediator(中介者接口)ChatMediator接口

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

ConcreteMediator(具体中介者)ChatRoom

class ChatRoom 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.receiveMessage(message);
            }
        }
    }
}

Colleague(同事类)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 + " sends: " + message);
        mediator.sendMessage(message, this);
    }

    public void receiveMessage(String message) {
   
        System.out.println(name + " received: " + message);
    }
}

测试类

public class ChatRoomWithMediator {
   
    public static void main(String[] args) {
   
        ChatMediator chatRoom = new ChatRoom();

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

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

        alice.sendMessage("Hi everyone!");
        bob.sendMessage("Hello Alice!");
    }
}

二、中介者模式在框架源码中的运用

Java 中的 java.util.Timer

Timer类可以看作是一个中介者,它负责调度和管理多个TimerTask对象。TimerTask是具体的同事类,它们通过Timer来协调任务的执行。

  • Timer 作为中介者,负责调度和执行任务。
  • TimerTask 不需要知道其他任务的存在,只需通过Timer来安排自己的执行。
import java.util.Timer;
import java.util.TimerTask;

public class TimerExample {
   
    public static void main(String[] args) {
   
        Timer timer = new Timer(); // 中介者

        TimerTask task1 = new TimerTask() {
   
            @Override
            public void run() {
   
                System.out.println("Task 1 is running.");
            }
        };

        TimerTask task2 = new TimerTask() {
   
            @Override
            public void run() {
   
                System.out.println("Task 2 is running.");
            }
        };

        // 通过中介者安排任务
        timer.schedule(task1, 1000); // 1秒后执行
        timer.schedule(task2, 2000); // 2秒后执行
    }
}

Spring 框架中的 ApplicationContext

在 Spring 框架中,ApplicationContext可以看作是一个中介者,它负责管理 Bean 的创建、依赖注入和生命周期。

  • ApplicationContext 作为中介者,集中管理所有 Bean 的交互。
  • Bean 之间不需要直接依赖,而是通过 ApplicationContext 获取依赖。
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

class ServiceA {
   
    public void doSomething() {
   
        System.out.println("Service A is doing something.");
    }
}

class ServiceB {
   
    private final ServiceA serviceA;

    public ServiceB(ServiceA serviceA) {
   
        this.serviceA = serviceA;
    }

    public void doSomething() {
   
        System.out.println("Service B is doing something.");
        serviceA.doSomething();
    }
}

public class SpringExample {
   
    public static void main(String[] args) {
   
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        ServiceB serviceB = context.getBean(ServiceB.class);
        serviceB.doSomething();
    }
}

三、总结

中介者模式的优点

  • 降低耦合度
    • 对象之间不再直接依赖,而是通过中介者进行通信。
    • 每个对象只需知道中介者,而不需要知道其他对象的存在。
  • 集中管理交互逻辑
    • 对象间的交互逻辑集中在中介者中,避免了逻辑分散。
    • 修改交互逻辑时,只需修改中介者,而不需要修改各个对象。
  • 提高系统的可扩展性
    • 新增对象时,只需修改中介者,而不需要修改现有对象。
    • 系统的扩展性和灵活性得到提升。
  • 简化代码结构
    • 对象间的依赖关系变得清晰,代码更易于理解和维护。
  • 增强可维护性
    • 由于交互逻辑集中在中介者中,调试和维护更加方便。

中介者模式的缺点

  • 中介者可能变得复杂
    • 如果对象间交互复杂,中介者可能会变得庞大且难以维护。
    • 中介者承担了过多的职责,可能违反单一职责原则。
  • 性能瓶颈
    • 所有交互都通过中介者进行,可能导致中介者成为性能瓶颈。
  • 过度集中化
    • 中介者集中了所有交互逻辑,可能导致系统过度依赖中介者,难以拆分或重构。

中介者模式的适用场景

  • 对象间交互复杂
    • 当多个对象之间存在复杂的交互关系,直接依赖会导致耦合度过高时,适合使用中介者模式。
  • 需要集中管理交互逻辑
    • 当对象间的交互逻辑分散在各个对象中,难以维护时,可以通过中介者集中管理。
  • 需要解耦对象间的依赖
    • 当对象之间需要解耦,避免直接依赖时,中介者模式是一个很好的选择。
  • 适用于事件驱动系统
    • 在事件驱动系统中,中介者可以充当事件分发器,集中管理事件的传递和处理。
  • GUI 开发
    • 在 GUI 开发中,中介者模式常用于管理组件间的交互,例如按钮点击、输入框变化等。
  • 多对多通信场景
    • 当多个对象需要相互通信,且通信关系复杂时,中介者模式可以简化通信逻辑。

参考

黑马程序员Java设计模式详解, 23种Java设计模式(图解+框架源码分析+实战)_哔哩哔哩_bilibili

目录
相关文章
|
10月前
|
设计模式 网络协议 Java
【设计模式】【行为型模式】状态模式(State)
一、入门 什么是状态模式? 状态模式(State Pattern)是一种行为设计模式,允许对象在其内部状态改变时改变其行为,使其看起来像是改变了类。状态模式的核心思想是将对象的状态封装成独立的类,并将
399 16
|
10月前
|
设计模式 算法 前端开发
【设计模式】【行为型模式】职责链模式(Chain of Responsibility)
一、入门 什么是职责链模式? 职责链模式是一种行为设计模式,它允许你将请求沿着一条链传递,直到有对象处理它为止。每个对象都有机会处理请求,或者将其传递给链中的下一个对象。 为什么需要职责链模式? 使用
366 16
|
10月前
|
设计模式 存储 Java
【设计模式】【行为型模式】备忘录模式(Memento)
一、入门 什么是备忘录模式? 备忘录模式(Memento Pattern)是一种行为设计模式,用于在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便在需要时恢复该状态。它通常用于实现撤销操作
327 8
|
10月前
|
设计模式 消息中间件 Java
【设计模式】【行为型模式】命令模式(Command)
一、入门 什么是命令模式? 命令模式是一种行为设计模式,它将请求或操作封装为对象,从而使你可以用不同的请求对客户进行参数化,并支持请求的排队、记录、撤销等操作。 命令模式的核心是将“请求”封装为独立的
290 15
|
10月前
|
设计模式 算法 搜索推荐
【设计模式】【行为型模式】策略模式(Strategy)
一、入门 什么是策略模式? 策略模式是一种行为设计模式,允许在运行时选择算法或行为。它将算法封装在独立的类中,使得它们可以互换,而不影响客户端代码。 为什么需要策略模式? 策略模式的主要目的是解决算法
224 14
|
10月前
|
设计模式 数据采集 算法
【设计模式】【行为型模式】模板方法模式(Template Method)
一、入门 1.1、什么是模板方法模式? 模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个算法的框架,并允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
311 13
|
10月前
|
设计模式 Java 编译器
【设计模式】【行为型模式】解释器模式(Interpreter)
一、入门 什么是解释器模式? 解释器模式(Interpreter Pattern)是一种行为设计模式,用于定义语言的语法表示,并提供一个解释器来处理该语法。它通常用于需要解释和执行特定语言或表达式的场
236 11
|
10月前
|
设计模式 存储 JavaScript
【设计模式】【行为型模式】迭代器模式(Iterator)
一、入门 什么是迭代器模式? 迭代器模式(Iterator Pattern)是一种行为设计模式,它提供了一种顺序访问聚合对象中元素的方法,而不需要暴露其底层表示。迭代器模式将遍历逻辑从聚合对象中分离出
271 11
|
10月前
|
设计模式 XML JSON
【设计模式】【行为型模式】访问者模式(Visitor)
一、入门 什么是访问者模式? 访问者模式(Visitor Pattern)是一种行为设计模式,允许你将算法与对象结构分离。通过这种方式,可以在不改变对象结构的情况下,向对象结构中的元素添加新的操作。
323 10
|
10月前
|
设计模式 消息中间件 存储
【设计模式】【行为型模式】观察者模式(Observer)
一、入门 什么是观察者模式? 观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。
459 9