Java中介者模式:对象间解耦通信
中介者模式(Mediator Pattern)是一种行为设计模式,通过引入一个中介对象来封装一组对象之间的交互,从而减少对象间的直接耦合。

核心概念
解决的问题:当多个对象之间存在复杂交互关系时,每个对象都需要知道其他对象的存在,形成网状结构,导致系统难以维护和扩展。
解决方案:将所有对象的交互逻辑集中到中介者中,形成星型结构。
结构图
┌─────────────┐ ┌─────────────┐
│ Colleague │ │ Mediator │
│ (同事对象) │◄────┤ (中介者接口)│
└──────┬──────┘ └──────┬──────┘
│ │
┌────┴────┐ ┌────┴────┐
│ Concrete │ │ Concrete│
│ Colleague│ │ Mediator│
└──────────┘ └─────────┘
▲ ▲
│ │
┌────┴────┐ │
│Concrete │──────────────┘
│Colleague│
└─────────┘
经典实现示例:聊天室
// 1. 中介者接口
interface ChatMediator {
void sendMessage(String message, User user);
void addUser(User user);
}
// 2. 具体中介者
class ChatRoom implements ChatMediator {
private List<User> users = new ArrayList<>();
@Override
public void addUser(User user) {
users.add(user);
System.out.println(user.getName() + " 加入了聊天室");
}
@Override
public void sendMessage(String message, User sender) {
for (User user : users) {
// 消息不需要发送给自己
if (user != sender) {
user.receive(message, sender.getName());
}
}
}
}
// 3. 同事对象抽象类
abstract class User {
protected ChatMediator mediator;
private String name;
public User(ChatMediator 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. 具体同事对象
class ChatUser extends User {
public ChatUser(ChatMediator mediator, String name) {
super(mediator, name);
}
@Override
public void send(String message) {
System.out.println(getName() + " 发送消息: " + message);
mediator.sendMessage(message, this);
}
@Override
public void receive(String message, String senderName) {
System.out.println(getName() + " 收到来自 " + senderName + " 的消息: " + message);
}
}
// 5. 使用示例
public class MediatorDemo {
public static void main(String[] args) {
ChatMediator chatRoom = new ChatRoom();
User alice = new ChatUser(chatRoom, "Alice");
User bob = new ChatUser(chatRoom, "Bob");
User charlie = new ChatUser(chatRoom, "Charlie");
chatRoom.addUser(alice);
chatRoom.addUser(bob);
chatRoom.addUser(charlie);
alice.send("大家好!");
System.out.println("---");
bob.send("你好, Alice!");
}
}
高级实现:航班控制系统
// 更复杂的例子:机场航班调度系统
interface AirportMediator {
void requestLanding(Flight flight);
void requestTakeoff(Flight flight);
void notifyRunwayStatus(int runwayNumber, boolean isAvailable);
void notifyWeatherChange(String weather);
}
class AirportControl implements AirportMediator {
private Map<Integer, Boolean> runways = new HashMap<>();
private List<Flight> flights = new ArrayList<>();
private String currentWeather = "晴朗";
public AirportControl() {
runways.put(1, true); // 跑道1可用
runways.put(2, true); // 跑道2可用
}
@Override
public void requestLanding(Flight flight) {
if (!"晴朗".equals(currentWeather)) {
flight.deny("天气条件不适合降落");
return;
}
for (Map.Entry<Integer, Boolean> entry : runways.entrySet()) {
if (entry.getValue()) {
runways.put(entry.getKey(), false);
flight.approve("允许降落,使用跑道 " + entry.getKey());
return;
}
}
flight.deny("所有跑道繁忙,请等待");
}
@Override
public void requestTakeoff(Flight flight) {
if (!"晴朗".equals(currentWeather)) {
flight.deny("天气条件不适合起飞");
return;
}
for (Map.Entry<Integer, Boolean> entry : runways.entrySet()) {
if (entry.getValue()) {
runways.put(entry.getKey(), false);
flight.approve("允许起飞,使用跑道 " + entry.getKey());
// 模拟起飞后跑道释放
new Timer().schedule(new TimerTask() {
@Override
public void run() {
runways.put(entry.getKey(), true);
notifyRunwayStatus(entry.getKey(), true);
}
}, 5000);
return;
}
}
flight.deny("所有跑道繁忙,请等待");
}
@Override
public void notifyRunwayStatus(int runwayNumber, boolean isAvailable) {
System.out.println("跑道 " + runwayNumber + " quot; + (isAvailable ? "可用" : "不可用"));
}
@Override
public void notifyWeatherChange(String weather) {
this.currentWeather = weather;
System.out.println("天气变化: " + weather);
// 通知所有航班
for (Flight flight : flights) {
flight.weatherAlert(weather);
}
}
}
class Flight {
private AirportMediator mediator;
private String flightNumber;
public Flight(AirportMediator mediator, String flightNumber) {
this.mediator = mediator;
this.flightNumber = flightNumber;
}
public void requestLanding() {
mediator.requestLanding(this);
}
public void requestTakeoff() {
mediator.requestTakeoff(this);
}
public void approve(String message) {
System.out.println("航班 " + flightNumber + ": " + message + " ✓");
}
public void deny(String reason) {
System.out.println("航班 " + flightNumber + ": 请求拒绝 - " + reason + " ✗");
}
public void weatherAlert(String weather) {
System.out.println("航班 " + flightNumber + " 注意: 天气变为 " + weather);
}
}
使用场景
- GUI组件通信:对话框中的按钮、文本框、列表等组件交互
- 消息系统:聊天应用、消息队列
- 游戏系统:玩家、NPC、环境之间的交互
- 工作流系统:任务分配、状态流转
- 物联网设备协调:智能家居设备联动
优缺点分析
优点:
- ✅ 减少对象间耦合,每个对象只需知道中介者
- ✅ 将多对多交互简化为一对多交互
- ✅ 集中控制交互逻辑,便于维护
- ✅ 提高系统可扩展性
缺点:
- ❌ 中介者可能变得复杂庞大(上帝对象反模式)
- ❌ 增加系统复杂度
- ❌ 中介者故障会影响所有交互
与其他模式关系
- 观察者模式:中介者可结合观察者模式实现事件通知
- 命令模式:中介者可以管理命令的执行
- 外观模式:中介者封装交互,外观封装子系统
最佳实践
- 控制中介者复杂度:当中介者变得庞大时,考虑拆分为多个专门中介者
- 组合使用事件驱动:结合观察者模式实现松耦合通信
- 使用接口抽象:定义清晰的中介者和同事接口
- 考虑使用消息队列:在分布式系统中,可用消息队列替代中介者
中介者模式特别适合处理复杂交互场景,能显著提高系统的可维护性和扩展性。