2025/10/15日 每日总结 设计模式实践:中介者模式之虚拟聊天室案例解析

设计模式实践:中介者模式之虚拟聊天室案例解析

在多对象交互频繁的场景中,对象间直接耦合会导致系统复杂度飙升、维护困难。中介者模式通过引入“中介者”角色,让所有对象通过中介者间接通信,从而降低对象间的直接耦合,将复杂的多对多关系转化为简单的一对多关系。本文将通过带限制条件的虚拟聊天室案例,详细拆解中介者模式的实现逻辑与应用价值。

一、实验背景与需求

本次实践的核心需求是扩展虚拟聊天室功能,新增带限制的聊天室和增强型会员,具体要求如下:

  1. 新聊天室规则:文本消息长度≤100字符,图片大小≤20MB(超出则拦截并提示)

  2. 新会员能力:支持发送文本消息(自动添加时间戳)和图片消息

  3. 核心约束:会员间不直接通信,所有消息通过聊天室(中介者)转发

  4. 保留原有功能:支持会员加入/退出、聊天记录存储与打印

二、中介者模式核心结构

中介者模式的关键在于“中介者”统一管理对象交互逻辑,“同事类”仅与中介者通信,不直接交互。本次案例的结构设计如下:

1. 核心组件划分

组件类型 具体实现 职责描述
抽象中介者 ChatRoom(抽象聊天室) 定义中介者核心接口,维护同事类(会员)列表,声明消息转发方法
具体中介者 ConcreteChatRoom(具体聊天室) 实现消息/图片发送逻辑,添加长度/大小限制,存储聊天记录
抽象同事类 Member(抽象会员) 定义会员的基本接口(发送消息),存储会员名称
具体同事类 ConcreteMember(具体会员) 实现发送文本(带时间戳)和图片的功能,通过中介者转发消息

2. 类图结构

┌─────────────────┐
│ ChatRoom │ ← 抽象中介者(聊天室)
├─────────────────┤
│ - members: List<Member> │ ← 维护会员列表
│ - messages: List<String> │ ← 存储聊天记录
├─────────────────┤
│ + addMember(member: Member): void │ ← 添加会员
│ + removeMember(member: Member): void │ ← 移除会员
│ + abstract sendMessage(sender: Member, msg: String): void │ ← 转发文本消息(抽象)
└─────────────────┘
▲
│
┌───────────────┐
│ConcreteChatRoom│ ← 具体中介者(带限制的聊天室)
├───────────────┤
│ - MAX_TEXT_LENGTH: int = 100 │ ← 文本长度限制
│ - MAX_IMAGE_SIZE: int = 20MB │ ← 图片大小限制
├───────────────┤
│ + sendMessage(sender: Member, msg: String): void │ ← 实现文本发送(含长度校验)
│ + sendImage(sender: Member, image: byte[]): void │ ← 新增图片发送(含大小校验)
│ + printMessages(): void │ ← 打印聊天记录
└───────────────┘
▲
│
┌─────────────────┐
│ Member │ ← 抽象同事类(会员)
├─────────────────┤
│ - name: String │ ← 会员名称
├─────────────────┤
│ + Member(name: String) │
│ + getName(): String │
│ + abstract sendMessage(msg: String): void │ ← 发送文本消息(抽象)
└─────────────────┘
▲
│
┌───────────────┐
│ConcreteMember │ ← 具体同事类(增强型会员)
├───────────────┤
│ - chatRoom: ConcreteChatRoom │ ← 持有中介者引用
├───────────────┤
│ + ConcreteMember(name: String, chatRoom: ConcreteChatRoom) │ ← 构造时自动加入聊天室
│ + sendMessage(msg: String): void │ ← 发送带时间戳的文本
│ + sendImage(image: byte[]): void │ ← 发送图片
└───────────────┘

三、完整实现代码(Java)

1. 抽象中介者:ChatRoom.java

import java.util.ArrayList;
import java.util.List;
/**
* 抽象聊天室类 - 中介者核心接口
*/
abstract class ChatRoom {
// 维护聊天室会员列表
protected List<Member> members = new ArrayList<>();
// 存储聊天记录
protected List<String> messages = new ArrayList<>();
// 添加会员到聊天室
public void addMember(Member member) {
members.add(member);
}
// 从聊天室移除会员
public void removeMember(Member member) {
members.remove(member);
}
// 转发文本消息(抽象方法,由具体聊天室实现)
public abstract void sendMessage(Member sender, String message);
}

2. 具体中介者:ConcreteChatRoom.java

/**
* 具体聊天室 - 带限制的中介者实现
*/
class ConcreteChatRoom extends ChatRoom {
// 文本消息最大长度(100字符)
private static final int MAX_TEXT_LENGTH = 100;
// 图片最大大小(20MB = 20*1024*1024 字节)
private static final int MAX_IMAGE_SIZE = 20 * 1024 * 1024;
@Override
public void sendMessage(Member sender, String message) {
// 校验文本长度
if (message.length() > MAX_TEXT_LENGTH) {
System.out.println("消息内容超出最大字数限制(100字符)!");
return;
}
// 存储聊天记录(含发送者)
String fullMessage = sender.getName() + ": " + message;
messages.add(fullMessage);
System.out.println("发送成功: " + fullMessage);
}
// 新增:发送图片(含大小校验)
public void sendImage(Member sender, byte[] image) {
if (image.length > MAX_IMAGE_SIZE) {
System.out.println("图片大小超出最大限制(20MB)!");
return;
}
System.out.println(sender.getName() + " 发送了一张图片");
}
// 打印所有聊天记录
public void printMessages() {
System.out.println("\n=== 聊天记录 ===");
for (String msg : messages) {
System.out.println(msg);
}
}
}

3. 抽象同事类:Member.java

/**
* 抽象会员类 - 同事类接口
*/
abstract class Member {
protected String name;
// 构造函数:初始化会员名称
public Member(String name) {
this.name = name;
}
// 获取会员名称
public String getName() {
return name;
}
// 发送文本消息(抽象方法,由具体会员实现)
public abstract void sendMessage(String message);
}

4. 具体同事类:ConcreteMember.java

import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 具体会员类 - 支持文本(带时间戳)和图片发送
*/
class ConcreteMember extends Member {
// 持有中介者(聊天室)引用,仅与中介者通信
private ConcreteChatRoom chatRoom;
// 构造函数:创建时自动加入聊天室
public ConcreteMember(String name, ConcreteChatRoom chatRoom) {
super(name);
this.chatRoom = chatRoom;
this.chatRoom.addMember(this);
}
@Override
public void sendMessage(String message) {
// 新增:文本消息添加时间戳
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String timeStamp = sdf.format(new Date());
String messageWithTime = message + " (发送时间: " + timeStamp + ")";

// 不直接发送,通过中介者转发
chatRoom.sendMessage(this, messageWithTime);
}
// 新增:发送图片
public void sendImage(byte[] image) {
chatRoom.sendImage(this, image);
}
}

### 5. 客户端测试类:Main.java
```java
/**
 * 测试类:验证聊天室功能(文本/图片发送、限制校验、聊天记录)
 */
public class Main {
 public static void main(String[] args) {
 // 1. 创建中介者(带限制的聊天室)
 ConcreteChatRoom chatRoom = new ConcreteChatRoom();
 // 2. 创建同事类(会员),自动加入聊天室
 ConcreteMember alice = new ConcreteMember("Alice", chatRoom);
 ConcreteMember bob = new ConcreteMember("Bob", chatRoom);
 // 3. 测试1:发送正常文本消息(带时间戳)
 System.out.println("=== 正常文本测试 ===");
 alice.sendMessage("你好,这是中介者模式实现的聊天室!");
 bob.sendMessage("Hi Alice,我能发送带时间戳的消息~");
 // 4. 测试2:发送超长文本(触发限制)
 System.out.println("\n=== 超长文本测试 ===");
 String longMsg = "这是一条超过100字符的测试消息,用来验证聊天室的文本长度限制功能。设计模式真的很有用,中介者模式能帮我们解耦对象间的交互,让代码更易维护!";
 alice.sendMessage(longMsg);
 // 5. 测试3:发送正常大小图片(15MB)
 System.out.println("\n=== 正常图片测试 ===");
 byte[] normalImage = new byte[15 * 1024 * 1024]; // 15MB
 alice.sendImage(normalImage);
 // 6. 测试4:发送超大图片(25MB,触发限制)
 System.out.println("\n=== 超大图片测试 ===");
 byte[] largeImage = new byte[25 * 1024 * 1024]; // 25MB
 bob.sendImage(largeImage);
 // 7. 测试5:打印聊天记录
 chatRoom.printMessages();
 }
}

四、运行结果

=== 正常文本测试 ===
发送成功: Alice: 你好,这是中介者模式实现的聊天室! (发送时间: 2024-05-20 14:30:45)
发送成功: Bob: Hi Alice,我能发送带时间戳的消息~ (发送时间: 2024-05-20 14:30:46)
=== 超长文本测试 ===
消息内容超出最大字数限制(100字符)!
=== 正常图片测试 ===
Alice 发送了一张图片
=== 超大图片测试 ===
图片大小超出最大限制(20MB)!
=== 聊天记录 ===
Alice: 你好,这是中介者模式实现的聊天室! (发送时间: 2024-05-20 14:30:45)
Bob: Hi Alice,我能发送带时间戳的消息~ (发送时间: 2024-05-20 14:30:46)

五、中介者模式核心优势与特性

1. 核心优势

  • 解耦对象交互:会员间无需知道彼此存在,所有通信通过聊天室转发,避免多对多直接耦合

  • 集中管理逻辑:文本长度、图片大小等限制规则集中在聊天室,修改时无需改动会员类,维护更高效

  • 扩展性强:新增功能(如消息撤回、@某人)只需修改中介者,或新增中介者子类,符合开闭原则

  • 简化对象职责:会员仅需关注“发送消息”,无需处理消息校验、转发等逻辑,职责单一

    2. 适用场景与注意事项

    适用场景

  • 多对象间交互频繁,形成复杂网络(如聊天室、即时通讯、工作流系统)

  • 需统一管理交互规则(如权限校验、格式限制、日志记录)

  • 希望降低对象耦合,提高系统可维护性

    注意事项

  • 中介者可能成为“上帝类”:需合理拆分逻辑,避免中介者过于庞大

  • 适合交互规则相对稳定的场景:若规则频繁变化,中介者可能频繁修改

  • 避免过度使用:简单的对象交互无需引入中介者,否则会增加系统复杂度

    六、总结

    通过本次虚拟聊天室的实践案例,深刻体会到中介者模式在解耦多对象交互中的核心价值。它将分散在各个对象中的交互逻辑集中到中介者,让对象专注于自身核心职责,同时让系统结构更清晰、维护更便捷。
    在实际开发中,除了聊天室,中介者模式还广泛应用于电商订单流程(订单、支付、库存、物流通过订单管理器协调)、团队协作工具(成员通过平台交互)等场景。合理运用中介者模式,能有效解决多对象耦合带来的维护难题。

posted @ 2025-12-29 14:38  Moonbeamsc  阅读(16)  评论(0)    收藏  举报
返回顶端