一、生活场景引入(非技术角度)
场景1:机场塔台的智慧(空中交通管制)
想象一个繁忙的国际机场,有上百架飞机需要同时完成起降。如果没有塔台指挥会发生什么?
-
混乱的原始状态 :
每架飞机都试图直接与其他飞机通信:
✈️ 国航123:"东航456!我要降落3号跑道,别挡路!"
✈️ 东航456:"深航789!你离我太近了,快让开!"
✈️ 美航888:"谁看到我的停机位了?"
➡️ 无线电频道混乱不堪,飞行员需要记住所有飞机的动态
-
塔台的出现 :
🛕 塔台成为唯一协调者:
✈️ 所有飞机只与塔台通信
🛑 塔台掌握全局信息(跑道占用、天气、航线)
✅ 简单清晰的指令:
"国航123,允许降落2号跑道"
"东航456,保持高度3000米盘旋等待"
关键启示 :塔台把 N×N 的通信网络 简化为 N×1 的星型结构
场景2:微信群聊的日常(消息中转中心)
假设公司有三个同事 Alice、Bob、Charlie 需要沟通:
-
原始沟通方式 (无微信群):
📱 Alice 需要分别给 Bob 和 Charlie 发同样的消息
📧 Bob 想分享文件,要逐个发送给其他两人
❌ 问题:联系人管理复杂,新人加入需要所有人更新通讯录
-
微信群解决方案 :
🟩 创建"项目攻坚群"作为消息枢纽
📨 任何人发消息到群里,自动同步给所有成员
➕ 新人加入只需扫码入群,无需逐个添加好友
场景对比与模式提炼
场景 | 混乱点 | 解决方案 | 本质思想 |
---|---|---|---|
机场调度 | 飞机间直接通信混乱 | 引入塔台中介 | 集中控制 |
微信沟通 | 点对点消息重复发送 | 创建群聊中介 | 信息中转 |
共性 | 多对象网状交互 | 统一协调中心 | 解耦对象间直接依赖 |
小白秒懂总结 :
当中介者不存时,对象间像没有指挥的交通路口;而中介者就像智能红绿灯,让所有车辆(对象)只需与红绿灯(中介)交互,不再需要关注其他车辆的具体动向。
二、模式解密(UML图)
用「群聊系统」理解类图结构
让我们通过微信群聊的场景,用大白话解释这个UML图的每个组成部分:
🧩 核心组件拆解(对照微信群案例)
1. 中介者接口(Mediator)------ 群规制定者
- 角色:相当于微信的群功能规范
- 作用 :
- 定义消息转发规则(比如是否允许@所有人)
- 声明核心方法
send
,所有具体群类型必须实现该规则
- 设计意义:通过接口约束,保证不同类型的群(工作群/亲友群)都遵守基本通信协议
2. 具体中介者(ConcreteMediator)------ 微信群实例
- 成员变量 :
users
:保存群成员列表(相当于微信群成员列表)
- 关键方法 :
register()
:入群操作(扫码加群时触发)send()
:消息广播逻辑(决定消息是否全员可见或部分可见)
- 实际场景:
java
// 示例:发送消息时排除发送者自己
public void send(String msg, User sender) {
for (User u : users) {
if(u != sender) u.receive(msg);
}
}
3. 用户类(User)------ 群成员
- 成员变量 :
mediator
:持有群对象引用(用户必须加入群才能发言)
- 关键行为 :
send()
:点击发送按钮时,把消息交给群处理receive()
:接收群转发的消息(显示在聊天窗口)
- 设计亮点 :用户无需知道其他成员的存在,只需和群交互
🔗 类关系详解(对照UML箭头)
1. 实现关系(空心三角箭头)
- 类比:微信群(ConcreteMediator)必须遵守微信制定的群规范(Mediator)
- 技术意义:面向接口编程,方便扩展不同类型的群(如禁言群、匿名群)
2. 使用依赖(普通箭头)
- 现实映射:群成员通过微信APP(Mediator)发送消息
- 代码体现:
java
public class User {
private Mediator mediator; // 依赖中介者接口
public void send(String msg) {
mediator.send(msg, this); // 通过中介者发送
}
}
3. 组合关系(实心菱形箭头)
- 现实意义:微信群对象持有所有群成员的引用
- 代码体现:
java
public class ChatRoom implements Mediator {
private List<User> users = new ArrayList<>(); // 组合用户对象
}
- 生命周期:当微信群解散时,成员引用自动清除
💡 架构设计亮点总结
- 星型拓扑结构:所有交互都经过中心节点(对比直接通信的网状结构)
- 双重解耦 :
- 用户不知道其他用户的存在
- 中介者不关心具体业务逻辑(可通过不同ConcreteMediator实现不同策略)
- 开放扩展:要增加新群类型(如视频群),只需新建ConcreteMediator实现类
三、问题场景(没有中介者的困境)
用一个「相亲相爱一家人」群聊的悲剧故事
假设我们要实现家庭群聊功能,先看看没有中介者时会发生什么:
java
// 问题代码示例:每个用户都要维护所有联系人
class User {
private String name;
private List<User> contacts = new ArrayList<>(); // 通讯录
public void addContact(User user) {
contacts.add(user);
}
public void sendDirectMessage(String msg, User to) {
System.out.println(name + " 私聊 " + to.name + ": " + msg);
to.receiveDirectMessage(msg, this);
}
// 群发消息的灾难性实现
public void broadcast(String msg) {
for (User contact : contacts) {
sendDirectMessage(msg, contact);
}
}
}
💥 问题集中爆发时刻(代码演示)
场景:妈妈想把菜谱分享给全家人
java
public static void main(String[] args) {
User 妈妈 = new User("妈妈");
User 爸爸 = new User("爸爸");
User 我 = new User("我");
User 爷爷 = new User("爷爷");
// 每个用户都要添加其他联系人
妈妈.addContact(爸爸);
妈妈.addContact(我);
妈妈.addContact(爷爷);
爸爸.addContact(妈妈);
爸爸.addContact(我);
// 爸爸忘记添加爷爷...
// 妈妈发送群发消息
妈妈.broadcast("新学的红烧肉做法!");
}
运行结果:
arduino
妈妈 私聊 爸爸: 新学的红烧肉做法!
妈妈 私聊 我: 新学的红烧肉做法!
妈妈 私聊 爷爷: 新学的红烧肉做法!
爸爸 收到消息: 新学的红烧肉做法! // 正常
我 收到消息: 新学的红烧肉做法! // 正常
爷爷 收到消息: 新学的红烧肉做法! // 正常
似乎正常?但隐藏着致命问题...
🚨 四大痛点分析
-
维护成本爆炸
每新增一个家庭成员(如奶奶),所有人都要修改通讯录:
java妈妈.addContact(奶奶); 爸爸.addContact(奶奶); 我.addContact(奶奶); 爷爷.addContact(奶奶); // 漏掉一个就会导致奶奶收不到消息
-
消息不一致风险
当爸爸忘记添加爷爷的联系方式时:
java// 爸爸想通知家人加班 爸爸.broadcast("今晚加班不回家吃饭"); // 爷爷永远收不到这个消息
-
功能扩展困难
若要实现@指定人功能:
javapublic void sendTo(String msg, List<User> targets) { // 需要判断每个target是否在自己的通讯录中 }
每个用户都要实现复杂的目标过滤逻辑
-
对象关系混乱
graph TD 妈妈 --> 爸爸 妈妈 --> 我 妈妈 --> 爷爷 爸爸 --> 妈妈 爸爸 --> 我 我 --> 妈妈 我 --> 爸爸 我 --> 爷爷 %% 形成复杂的网状结构
💡 关键问题总结
问题类型 | 具体表现 | 类比现实 |
---|---|---|
强耦合 | 用户直接持有其他用户的引用 | 每个家庭成员的手机里存着所有人的电话号码 |
高维护成本 | 添加/删除用户需要联动修改多处 | 家族有新成员出生,所有亲戚的通讯录都要更新 |
低扩展性 | 新增功能(如消息撤回)需修改所有用户类 | 每家都要自建信号塔才能通信 |
单点故障 | 某个用户出错会影响整个通信链路 | 某人的手机没电导致全家失联 |
四、解决方案(引入中介者)
用「小区快递柜」类比消息中转
让我们通过更生活化的例子,理解这个架构图的工作流程:
🛠️ 新架构核心原理(三步流程)
步骤1:用户发送消息到中介者
java
// User类中的发送方法
public void send(String msg) {
System.out.println(name + " 发出消息:" + msg);
mediator.sendMessage(msg, this); // 把消息交给快递柜
}
- 类比:把包裹放入快递柜格口
- 技术意义:用户不再需要知道接收者是谁
步骤2:中介者处理消息
java
// ChatRoom中介者的消息处理
public void sendMessage(String msg, User sender) {
System.out.println("--- 中介者开始派发消息 ---");
for (User user : users) {
if(user != sender) { // 不送回发件人
user.receive(msg); // 将包裹放入收件人柜格
}
}
}
- 过滤逻辑:自动屏蔽发送者自身(类似快递柜不会把包裹存回寄件人柜格)
- 路由控制:集中处理消息分发策略(可在此扩展消息加密、敏感词过滤等功能)
步骤3:用户接收消息
java
// User类中的接收方法
public void receive(String msg) {
System.out.println(name + " 收到消息:" + msg);
}
- 类比:从快递柜取件
- 设计优势:接收方无需关心消息来源,专注处理内容
🔄 完整交互流程演示
场景:技术讨论群
java
public static void main(String[] args) {
// 创建中介者 - 相当于新建微信群
ChatMediator mediator = new ChatRoom();
// 创建用户并入群
User frontend = new User("前端开发", mediator);
User backend = new User("后端开发", mediator);
User pm = new User("产品经理", mediator);
// 发送消息
pm.send("需求文档已更新");
backend.send("接口已开发完成");
}
执行过程可视化:
控制台输出:
前端开发 收到消息:需求文档已更新
后端开发 收到消息:需求文档已更新
后端开发 发出消息:接口已开发完成
产品经理 收到消息:接口已开发完成
前端开发 收到消息:接口已开发完成
🆚 新旧方案对比
代码复杂度对比:
java
// 旧方案(用户直接交互)
userA.sendToAll("消息"); // 每个用户要自己遍历联系人
// 新方案(通过中介者)
userA.send("消息"); // 只需调用中介者的统一接口
对象关系变化:
C → M ← D"]
扩展性对比:
功能需求 | 旧方案改动点 | 新方案改动点 |
---|---|---|
添加消息已读回执 | 修改所有User类 | 只需修改ChatRoom类 |
实现@指定人功能 | 每个用户维护联系人关系 | 中介者统一管理用户列表 |
添加敏感词过滤 | 每个发送方法都要添加过滤逻辑 | 在中介者中统一处理 |
💡 架构升级收益总结
- 联系人零维护:用户不再需要持有其他对象的引用
- 集中管控点:所有消息处理逻辑收敛到中介者
- 扩展无侵入:新增功能只需修改中介者,不影响现有用户类
- 关系可视化:通过中介者的日志可以清晰追踪所有交互记录
- 资源节约:100个用户的群聊,消息发送次数从100×99=9900次减少到100次
现实映射:就像从原始部落的点对点物物交换,进化到现代物流中心的分发体系,中介者模式让系统交互进入了工业化时代。
五、完整代码实现(分步骤讲解)
1. 中介者接口:定义通信规则(相当于微信群协议)
java
/**
* 中介者接口:声明群聊的基本功能
* 相当于微信群的标准化功能定义
*/
public interface ChatMediator {
/**
* 发送消息给其他人
* @param msg 消息内容
* @param sender 发送者(用于排除自己)
*/
void sendMessage(String msg, User sender);
/**
* 添加用户到群聊
* @param user 要加入的用户
*/
void addUser(User user);
}
代码要点:
- 接口只定义两个核心功能:消息发送和用户添加
- 类似微信群的基础协议,所有具体群类型必须遵守
- 参数
sender
用于识别消息来源,实现不发送给自己的逻辑
2. 具体中介者:聊天室实现(完整版)
java
import java.util.ArrayList;
import java.util.List;
/**
* 具体中介者:微信群的具体实现
* 相当于一个工作群,自动排除发送者自身
*/
public 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 msg, User sender) {
System.out.println("\n【群消息中转】来自 " + sender.getName());
for (User user : users) {
// 关键逻辑:不将消息发回给发送者
if (user != sender) {
user.receive(msg); // 调用接收者的接收方法
}
}
}
}
代码升级说明:
- 增加入群提示(现实场景可扩展为入群欢迎语)
- 添加详细日志,显示消息中转过程
- 使用
getName()
方法代替直接访问字段(面向对象封装原则) - 导入必要的包(实际开发时容易忽略的细节)
3. 用户类:与中介者交互(增强版)
java
/**
* 用户类:不再维护任何联系人信息
* 相当于只关注自己与微信群的交互
*/
public class User {
private String name;
private ChatMediator mediator;
public User(String name, ChatMediator mediator) {
this.name = name;
this.mediator = mediator;
// 注册到群聊(相当于扫码加群)
mediator.addUser(this);
}
public String getName() {
return name;
}
public void send(String msg) {
System.out.println("\n[" + name + "] 点击发送按钮");
mediator.sendMessage(msg, this); // 只与中介者交互
}
public void receive(String msg) {
System.out.println(" " + name + " 的聊天窗口显示 <- " + msg);
}
}
新增特性:
- 封装
name
字段并提供访问方法 - 构造时自动注册到中介者(避免忘记添加用户)
- 模拟真实操作流程(点击发送按钮的日志)
- 更逼真的接收效果显示
4. 客户端使用(带运行结果演示)
java
/**
* 演示:家庭群聊场景
*/
public class FamilyChatDemo {
public static void main(String[] args) {
// 创建微信群(中介者)
ChatMediator familyWeChatGroup = new ChatRoom();
// 创建家庭成员(入群操作在构造函数自动完成)
User mother = new User("妈妈", familyWeChatGroup);
User father = new User("爸爸", familyWeChatGroup);
User son = new User("小明", familyWeChatGroup);
// 奶奶稍后入群
User grandma = new User("奶奶", familyWeChatGroup);
System.out.println("\n======== 开始群聊 ========");
mother.send("超市鸡蛋打折,要不要多买点?");
grandma.send("我手机怎么发不了图片啊?");
}
}
运行结果:
css
妈妈 加入了群聊
爸爸 加入了群聊
小明 加入了群聊
奶奶 加入了群聊
======== 开始群聊 ========
[妈妈] 点击发送按钮
【群消息中转】来自 妈妈
爸爸 的聊天窗口显示 <- 超市鸡蛋打折,要不要多买点?
小明 的聊天窗口显示 <- 超市鸡蛋打折,要不要多买点?
奶奶 的聊天窗口显示 <- 超市鸡蛋打折,要不要多买点?
[奶奶] 点击发送按钮
【群消息中转】来自 奶奶
妈妈 的聊天窗口显示 <- 我手机怎么发不了图片啊?
爸爸 的聊天窗口显示 <- 我手机怎么发不了图片啊?
小明 的聊天窗口显示 <- 我手机怎么发不了图片啊?
代码设计亮点解读
-
自动注册机制
java// 用户在创建时自动加入群聊 public User(String name, ChatMediator mediator) { mediator.addUser(this); }
- 避免忘记将用户添加到群聊
- 类似微信扫码加群的体验
-
双向解耦设计
graph LR User-->Mediator Mediator-->User- 用户不知道其他用户的存在
- 中介者只负责转发,不处理业务逻辑
-
开闭原则实践
javapublic class VIPChatRoom implements ChatMediator { // 可扩展为VIP专属群 }
- 新增群类型无需修改现有代码
- 可自由扩展消息过滤、@指定人等功能
可扩展性演示:添加敏感词过滤
java
/**
* 升级版中介者:带敏感词过滤的家长群
*/
public class ParentChatRoom extends ChatRoom {
private static final List<String> BANNED_WORDS =
List.of("打架", "逃课", "早恋");
@Override
public void sendMessage(String msg, User sender) {
// 过滤敏感词
String filteredMsg = filter(msg);
super.sendMessage(filteredMsg, sender);
}
private String filter(String original) {
String result = original;
for (String word : BANNED_WORDS) {
result = result.replace(word, "**");
}
return result;
}
}
// 使用示例
ChatMediator parentGroup = new ParentChatRoom();
new User("张老师", parentGroup).send("最近发现有些同学想早恋!");
// 输出:最近发现有些同学想**!
扩展提示:
- 只需新建中介者子类即可实现功能升级
- 完全不影响原有
User
类的实现 - 符合开闭原则(对扩展开放,对修改关闭)
六、模式优势总结(对比表格+实战解读)
用「微信群聊」案例理解优势差异
指标 | 无中介者(私聊模式) | 有中介者(群聊模式) | 实战影响 |
---|---|---|---|
对象耦合度 | 每个用户持有其他所有用户的引用 | 用户只持有群聊中介者引用 | 修改用户类不会影响消息系统,新增功能只需修改中介者类 |
新增用户成本 | 需要修改所有现有用户的联系人列表 | 只需调用mediator.addUser() |
100人群新增成员时,工作量从修改100个用户类减少到1次方法调用 |
消息控制 | 每个用户自己实现发送逻辑 | 在中介者中统一处理过滤、路由、日志 | 添加敏感词过滤功能只需修改中介者类,无需改动每个用户的发送方法 |
通信复杂度 | N个用户需要维护N×(N-1)个通信通道 | 只需维护N个用户到1个中介者的通道 | 用户数从10增加到100时,通信通道数从9900减少到100,降低两个数量级 |
错误排查 | 需要跟踪多个对象间的交互 | 所有交互记录在中介者日志中 | 快速定位消息丢失问题,类似微信群的"聊天记录"功能 |
七、实际应用场景(含代码片段)
场景1:GUI组件交互 - 登录表单验证
java
// 中介者接口
interface FormMediator {
void onUsernameChange(String text);
void onPasswordChange(String text);
void registerComponent(Component component);
}
// 具体中介者
class LoginFormMediator implements FormMediator {
private JTextField username;
private JPasswordField password;
private JButton submitButton;
@Override
public void onUsernameChange(String text) {
boolean valid = !text.isEmpty();
submitButton.setEnabled(valid && password.getPassword().length > 6);
}
@Override
public void registerComponent(Component component) {
if (component instanceof JTextField) {
username = (JTextField)component;
} else if (component instanceof JPasswordField) {
password = (JPasswordField)component;
}
}
}
// 使用示例
FormMediator mediator = new LoginFormMediator();
JTextField usernameField = new JTextField();
usernameField.addActionListener(e ->
mediator.onUsernameChange(usernameField.getText()));
// 其他组件类似注册...
工作原理:
场景2:微服务API网关 - 请求路由
java
// 简化版网关中介者
public class ApiGateway {
private Map<String, Service> services = new HashMap<>();
public void registerService(String path, Service service) {
services.put(path, service);
}
public Response handleRequest(Request request) {
Service service = services.get(request.getPath());
if (service != null) {
// 统一处理鉴权、限流
if (checkAuth(request)) {
return service.execute(request);
}
return new Response(403, "Forbidden");
}
return new Response(404, "Not Found");
}
}
// 客户端调用
ApiGateway gateway = new ApiGateway();
gateway.registerService("/order", new OrderService());
gateway.registerService("/payment", new PaymentService());
Response res = gateway.handleRequest(
new Request("/order?item=book", "GET"));
架构优势:
- 服务提供者无需关心身份验证等横切关注点
- 新增服务只需注册,客户端调用方式不变
场景3:游戏技能系统 - 技能连锁触发
java
class SkillMediator {
private List<Player> players = new ArrayList<>();
public void castSkill(Player caster, Skill skill) {
// 1. 计算伤害范围
// 2. 触发队友增益BUFF
// 3. 触发敌人减益效果
players.stream()
.filter(p -> inRange(p, caster))
.forEach(p -> {
if (isAlly(p, caster)) {
p.addBuff(skill.getBuff());
} else {
p.addDebuff(skill.getDebuff());
}
});
}
}
// 玩家释放技能时
public class Player {
private SkillMediator mediator;
public void useSkill(Skill skill) {
mediator.castSkill(this, skill);
}
}
设计亮点:
- 技能效果计算逻辑集中处理
- 新增技能类型不影响玩家类
场景4:工作流引擎 - 订单状态机
java
class OrderWorkflowMediator {
private Map<OrderState, List<StateHandler>> handlers = new HashMap<>();
public void transition(Order order, OrderState newState) {
// 1. 检查状态转换是否合法
// 2. 触发关联操作(发邮件、通知仓库等)
// 3. 更新状态
handlers.getOrDefault(newState, Collections.emptyList())
.forEach(handler -> handler.handle(order));
}
}
// 使用示例
mediator.transition(order, OrderState.SHIPPED);
业务流程:
八、最佳实践建议(避坑指南)
-
合理控制中介者规模
- 当一个中介者类超过1000行代码时,考虑拆分为多个专项中介者
- 示例:电商系统可拆分为
OrderMediator
、PaymentMediator
等
-
避免上帝对象
java// 错误示例:中介者包办一切 class BadMediator { void handleUser() { /* 用户管理 */ } void calcPrice() { /* 价格计算 */ } void generateReport() { /* 报表生成 */ } } // 正确做法:职责分离 class OrderMediator { /* 仅处理订单相关协调 */ } class ReportMediator { /* 仅处理报表生成协调 */ }
-
与观察者模式结合使用
java// 中介者内部使用观察者模式 class SmartMediator { private List<Consumer<Event>> listeners = new ArrayList<>(); public void addListener(Consumer<Event> listener) { listeners.add(listener); } private void notifyListeners(Event event) { listeners.forEach(l -> l.accept(event)); } }
-
性能优化策略
- 对高频交互场景使用缓存(如游戏技能中介者缓存伤害计算)
- 采用异步处理(如订单流程中介者使用消息队列)
九、延伸思考题(附解决方案思路)
Q1:中介者模式与观察者模式的异同?
场景对比分析 :
假设要实现一个新用户入群通知功能:
java
// 用观察者模式实现
class ChatGroup {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer o) {
observers.add(o);
}
private void notifyNewUser(User user) {
observers.forEach(o -> o.update("新用户加入:" + user));
}
}
// 用中介者模式实现
class ChatMediatorImpl {
private List<User> users = new ArrayList<>();
public void addUser(User user) {
users.add(user);
sendSystemMsg("欢迎 " + user + " 加入群聊");
}
}
核心差异总结:
维度 | 观察者模式 | 中介者模式 |
---|---|---|
交互方向 | 单向(主题 → 观察者) | 双向(同事 ↔ 中介者) |
关注点 | 状态变化通知 | 对象间交互协调 |
耦合度 | 观察者依赖主题 | 同事类只依赖中介者 |
典型场景 | 事件通知(如按钮点击) | 复杂交互协调(如聊天路由) |
控制权 | 由观察者决定是否响应 | 由中介者控制消息流向 |
组合使用案例:
java
// 在中介者内部使用观察者
class SmartMediator implements Mediator {
private List<Consumer<String>> listeners = new ArrayList<>();
public void addListener(Consumer<String> listener) {
listeners.add(listener);
}
public void send(String msg) {
// 先处理消息逻辑
String processedMsg = process(msg);
// 再通知观察者
listeners.forEach(l -> l.accept(processedMsg));
}
}
Q2:如何在中介者中实现定向消息发送?
场景需求:在群聊中实现@指定用户功能
解决方案:
-
消息协议设计 :
定义消息格式
@用户名 消息内容
-
修改中介者逻辑:
java
public class AdvancedChatRoom extends ChatRoom {
@Override
public void sendMessage(String msg, User sender) {
if (msg.startsWith("@")) {
// 定向消息处理
String[] parts = msg.split(" ", 2);
String targetName = parts[0].substring(1);
String content = parts.length > 1 ? parts[1] : "";
users.stream()
.filter(u -> u.getName().equals(targetName))
.findFirst()
.ifPresent(u -> u.receive("[私信] " + content));
} else {
// 广播消息
super.sendMessage(msg, sender);
}
}
}
- 客户端使用:
java
User bob = new User("Bob", mediator);
new User("Alice", mediator).send("@Bob 今晚一起吃饭吗?");
执行效果:
css
Bob 收到消息: [私信] 今晚一起吃饭吗?
扩展方案对比:
方案 | 优点 | 缺点 |
---|---|---|
消息协议解析 | 兼容现有接口 | 需要解析字符串 |
新增定向发送API | 接口明确 | 需要修改所有发送逻辑 |
消息对象封装 | 类型安全 | 增加系统复杂性 |
Q3:怎样防止中介者出现性能瓶颈?
典型瓶颈场景:
- 万人聊天室的消息广播
- 高频交易订单的状态流转
- 大型MMO游戏的技能结算
优化策略工具箱:
- 异步处理
java
class AsyncMediator {
private Executor executor = Executors.newFixedThreadPool(4);
private BlockingQueue<Message> queue = new LinkedBlockingQueue<>();
public void sendAsync(Message msg) {
queue.offer(msg);
executor.execute(() -> processQueue());
}
private void processQueue() {
while (!queue.isEmpty()) {
Message msg = queue.poll();
// 实际处理逻辑
}
}
}
适用场景:允许短暂延迟的消息系统
- 分片处理
实现示例:
java
class ShardedChatMediator {
private List<ChatMediator> shards = new ArrayList<>();
public ShardedChatMediator(int shardCount) {
for(int i=0; i<shardCount; i++) {
shards.add(new ChatRoom());
}
}
public void send(String msg, User user) {
int shardIndex = user.hashCode() % shards.size();
shards.get(shardIndex).send(msg, user);
}
}
- 缓存优化
java
class CachedMediator {
private Map<String, CacheEntry> cache = new ConcurrentHashMap<>();
public void process(Request req) {
String key = generateCacheKey(req);
CacheEntry entry = cache.get(key);
if (entry == null || entry.isExpired()) {
entry = computeResult(req);
cache.put(key, entry);
}
return entry.getValue();
}
}
适用场景:频繁重复计算的场景(如游戏伤害计算)
- 批量处理
java
class BatchMediator {
private List<Message> batch = new ArrayList<>();
public synchronized void send(Message msg) {
batch.add(msg);
if (batch.size() >= 100) {
flushBatch();
}
}
private void flushBatch() {
// 批量写入数据库或发送
}
}
性能优化决策树:
总结建议:
- 优先考虑异步非阻塞方案
- 根据业务特点选择分片策略(按用户ID哈希、按业务类型等)
- 对读多写少场景使用缓存+过期策略
- 监控中介者的消息处理延迟和队列长度
- 在微服务架构中可考虑将中介者部署为独立服务