Post

中介者模式

模式动机

如果一个模块由多个对象构成,对象之间存在相互地引用,为了减少对象两两之间复杂的引用关系,使之成为一个松耦合的系统,我们需要使用中介者模式

模式定义

中介者模式(Mediator Pattern)定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。(Mediator Pattern: Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.)

模式结构

模式结构图

中介者模式包含如下角色:

  • Mediator:抽象中介者(封装具体的交互细节)
  • ConcreteMediator:具体中介者
  • Colleague:抽象同事类
  • ConcreteColleague:具体同事类

模式分析

通过引入中介者对象,可以将系统的网状结构变成以中介者为中心的星形结构,中介者承担了中转作用和协调作用。

中介者模式承担两方面的职责:

  • 中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显示引用其他同事,当需要和其他同事进行通信时,通过中介者即可.该中转作用属于中介者在结构上的支持
  • 协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同时可以一致地和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装.该协调作用属于中介者在行为上的支持

模式适用环境

  • 系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解

  • 一个对象由于引用了其他很多对象并且直接和这些对象通信导致难以复用该对象。

  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的中介者类。

模式扩展

中介者模式与迪米特法则

在中介者模式中,通过创造出一个中介者对象,将系统中有关的对象所引用的其他对象数目减少到最少,使得一个对象与其同事之间的相互作用被这个对象与中介者对象之间的相互作用所取代。因此,中介者模式就是迪米特法则的一个典型应用

Java案例

// 中介者接口:定义消息传递的规范
public interface Mediator {
    void sendMessage(String message, Colleague sender);
}

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

// 具体中介者:聊天室
public class ChatRoomMediator implements Mediator {
  private List<Colleague> colleagues = new ArrayList<>();

  // 注册用户到聊天室
  public void addColleague(Colleague colleague) {
    colleagues.add(colleague);
  }

  @Override
  public void sendMessage(String message, Colleague sender) {
    // 将消息发送给所有用户(除了发送者自己)
    for (Colleague colleague : colleagues) {
      if (colleague != sender) {
        colleague.receive(message);
      }
    }
  }
}

// 同事类接口:用户
public abstract class Colleague {
  protected Mediator mediator;
  protected String name;

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

  // 发送消息
  public abstract void send(String message);

  // 接收消息
  public abstract void receive(String message);
}

// 具体同事类:用户
public class User extends Colleague {
    public User(Mediator mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void send(String message) {
        System.out.println(name + " 发送消息: " + message);
        mediator.sendMessage(message, this); // 通过中介者发送消息
    }

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

public class Main {
  public static void main(String[] args) {
    // 1. 创建中介者(聊天室)
    Mediator chatRoom = new ChatRoomMediator();

    // 2. 创建用户并注册到聊天室
    User userA = new User(chatRoom, "Alice");
    User userB = new User(chatRoom, "Bob");
    User userC = new User(chatRoom, "Charlie");

    ((ChatRoomMediator) chatRoom).addColleague(userA);
    ((ChatRoomMediator) chatRoom).addColleague(userB);
    ((ChatRoomMediator) chatRoom).addColleague(userC);

    // 3. 用户发送消息
    userA.send("大家好!");
    userB.send("今天天气不错!");
  }
}
This post is licensed under CC BY 4.0 by the author.