当前位置: 首页 > news >正文

11.30 实验十九中介者模式 实验二十备忘录模式

实验19:中介者模式
本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:
1、理解中介者模式的动机,掌握该模式的结构;
2、能够利用中介者模式解决实际问题。

[实验任务一]:虚拟聊天室
在“虚拟聊天室”实例中增加一个新的具体聊天室类和一个新的具体会员类,要求如下:

  1. 新的具体聊天室中发送的图片大小不得超过20M。
  2. 新的具体聊天室中发送的文字长度不得超过100个字符。
  3. 新的具体会员类可以发送图片信息和文本信息。
  4. 新的具体会员类在发送文本信息时,可以在信息后加上时间。
    修改客户端测试类,注意原有系统类代码和客户端代码的修改。
    实验要求:
    1.画出对应的类图;
    2.提交源代码;
  5. 注意编程规范。
    image
ChatroomMediator.java
/public interface ChatroomMediator {/*** 转发文本消息* @param sender 发送者* @param text 文本内容*/void sendText(Member sender, String text);/*** 转发图片消息* @param sender 发送者* @param imageName 图片名称* @param size 图片大小(字节)*/void sendImage(Member sender, String imageName, long size);}
CommonChatroom.java
public class CommonChatroom implements ChatroomMediator {@Overridepublic void sendText(Member sender, String text) {System.out.println("【普通聊天室】" + sender.getName() + "发送文本:" + text);}@Overridepublic void sendImage(Member sender, String imageName, long size) {System.out.println("【普通聊天室】" + sender.getName() + "发送图片:" + imageName + "(大小:" + size + "字节)");}}
RestrictedChatroom.java
public class RestrictedChatroom implements ChatroomMediator {// 文本最大长度:100字符private static final int MAX_TEXT_LENGTH = 100;// 图片最大大小:20M = 20 * 1024 * 1024 = 20971520字节private static final long MAX_IMAGE_SIZE = 20 * 1024 * 1024L;@Overridepublic void sendText(Member sender, String text) {if (text.length() > MAX_TEXT_LENGTH) {System.out.println("【受限聊天室】" + sender.getName() + "发送文本失败:长度超过" + MAX_TEXT_LENGTH + "字符(当前:" + text.length() + ")");return;}System.out.println("【受限聊天室】" + sender.getName() + "发送文本:" + text);}@Overridepublic void sendImage(Member sender, String imageName, long size) {if (size > MAX_IMAGE_SIZE) {System.out.println("【受限聊天室】" + sender.getName() + "发送图片失败:大小超过20M(当前:" + size / 1024 / 1024 + "M)");return;}System.out.println("【受限聊天室】" + sender.getName() + "发送图片:" + imageName + "(大小:" + size / 1024 / 1024 + "M)");}}
Member.java
public abstract class Member {// 会员姓名protected String name;// 关联的聊天室中介者protected ChatroomMediator mediator;/*** 构造方法:初始化姓名* @param name 会员姓名*/public Member(String name) {this.name = name;}/*** 设置聊天室中介者* @param mediator 聊天室实例*/public void setMediator(ChatroomMediator mediator) {this.mediator = mediator;}/*** 获取会员姓名* @return 姓名*/public String getName() {return name;}// 抽象方法:发送文本(子类实现)public abstract void sendText(String text);// 抽象方法:发送图片(子类实现)
public abstract void sendImage(String imageName, long size);}CommonMember.java
public class CommonMember extends Member {public CommonMember(String name) {super(name);}@Overridepublic void sendText(String text) {if (mediator != null) {mediator.sendText(this, text);} else {System.out.println("错误:未关联聊天室!");}}@Overridepublic void sendImage(String imageName, long size) {if (mediator != null) {mediator.sendImage(this, imageName, size);} else {System.out.println("错误:未关联聊天室!");}}}
AdvancedMember.java
public class AdvancedMember extends Member {// 时间格式化器private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");public AdvancedMember(String name) {super(name);}@Overridepublic void sendText(String text) {if (mediator != null) {// 追加当前时间戳String textWithTime = text + "【发送时间:" + LocalDateTime.now().format(TIME_FORMATTER) + "】";mediator.sendText(this, textWithTime);} else {System.out.println("错误:未关联聊天室!");}}@Overridepublic void sendImage(String imageName, long size) {if (mediator != null) {mediator.sendImage(this, imageName, size);} else {System.out.println("错误:未关联聊天室!");}
}}ChatroomTest.java
/public class ChatroomTest {public static void main(String[] args) {// 1. 创建聊天室中介者ChatroomMediator commonChatroom = new CommonChatroom();ChatroomMediator restrictedChatroom = new RestrictedChatroom();// 2. 创建会员Member commonUser = new CommonMember("普通用户A");Member advancedUser = new AdvancedMember("高级用户B");// 3. 普通会员加入普通聊天室System.out.println("===== 普通聊天室测试 =====");commonUser.setMediator(commonChatroom);commonUser.sendText("大家好!这是普通会员的消息");commonUser.sendImage("风景.jpg", 5 * 1024 * 1024); // 5M图片// 4. 高级会员加入受限聊天室System.out.println("\n===== 受限聊天室测试 =====");advancedUser.setMediator(restrictedChatroom);// 测试合法文本(带时间戳)advancedUser.sendText("受限聊天室的合法消息,长度小于100字符");// 测试超长文本advancedUser.sendText("这是一条超长的测试文本,目的是验证受限聊天室的文本长度限制,当前字符数明显超过100个,看看是否会被拦截");// 测试合法图片(10M)advancedUser.sendImage("头像.png", 10 * 1024 * 1024);// 测试超大图片(25M)advancedUser.sendImage("视频截图.png", 25 * 1024 * 1024);// 5. 普通会员加入受限聊天室System.out.println("\n===== 普通会员在受限聊天室测试 =====");commonUser.setMediator(restrictedChatroom);commonUser.sendText("普通会员在受限聊天室的消息");commonUser.sendImage("文件.png", 21 * 1024 * 1024); // 21M图片(超限)}}

实验 20:备忘录模式
本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:
1、理解备忘录模式的动机,掌握该模式的结构;
2、能够利用备忘录模式解决实际问题。

[实验任务一]:多次撤销
改进课堂上的“用户信息操作撤销”实例,使得系统可以实现多次撤销(可以使用HashMap、ArrayList等集合数据结构实现)。
实验要求:
1.画出对应的类图;
2.提交源代码;
3. 注意编程规范。
image

UserMemento.java
public class UserMemento {// 保存的用户状态(与原发器一致)private final String name;private final int age;private final String phone;/*** 构造方法:初始化备忘录状态(仅原发器可调用)* @param name 姓名* @param age 年龄* @param phone 手机号*/public UserMemento(String name, int age, String phone) {this.name = name;this.age = age;this.phone = phone;}// 只读getter方法,供原发器恢复状态public String getName() {return name;}public int getAge() {return age;}public String getPhone() {return phone;
}}UserInfo.java
public class UserInfo {// 用户状态属性private String name;private int age;private String phone;/*** 构造方法:初始化用户信息* @param name 姓名* @param age 年龄* @param phone 手机号*/public UserInfo(String name, int age, String phone) {this.name = name;this.age = age;this.phone = phone;}/*** 创建备忘录:保存当前状态* @return 包含当前状态的备忘录*/public UserMemento createMemento() {return new UserMemento(name, age, phone);}/*** 恢复备忘录:从备忘录中回滚状态* @param memento 要恢复的备忘录*/public void restoreMemento(UserMemento memento) {this.name = memento.getName();this.age = memento.getAge();this.phone = memento.getPhone();}// 属性修改方法(每次修改前需保存当前状态到管理者)public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public void setPhone(String phone) {this.phone = phone;}/*** 显示当前用户状态*/public void show() {System.out.println("当前用户信息:姓名=" + name + ",年龄=" + age + ",手机号=" + phone);
}}Caretaker.java
import java.util.ArrayList;import java.util.List;
public class Caretaker {// 存储备忘录的列表(按操作顺序保存)private final List<UserMemento> mementos = new ArrayList<>();// 当前状态索引(指向最新备忘录的下一个位置)private int currentIndex = 0;/*** 保存备忘录到列表* @param memento 要保存的备忘录*/public void saveMemento(UserMemento memento) {// 如果是中间撤销后新增操作,清除后续的备忘录(避免redo冲突)if (currentIndex < mementos.size()) {mementos.subList(currentIndex, mementos.size()).clear();}mementos.add(memento);currentIndex++;}/*** 撤销操作:获取上一个备忘录* @return 上一个状态的备忘录,无则返回null*/public UserMemento undo() {if (canUndo()) {currentIndex--;return mementos.get(currentIndex - 1); // 索引-1为上一个状态}System.out.println("⚠️  无历史状态可撤销!");return null;}/*** 判断是否可撤销* @return true=可撤销,false=不可撤销*/public boolean canUndo() {return currentIndex > 1; // 至少有一个历史状态(初始状态为索引0)
}}MementoTest.java
public class MementoTest {public static void main(String[] args) {// 1. 初始化原发器(用户信息)和管理者UserInfo user = new UserInfo("张三", 20, "13800138000");Caretaker caretaker = new Caretaker();// 2. 保存初始状态(首次操作前必须保存)caretaker.saveMemento(user.createMemento());System.out.println("===== 初始状态 =====");user.show();// 3. 修改状态1:更新姓名和年龄user.setName("李四");user.setAge(22);caretaker.saveMemento(user.createMemento());System.out.println("\n===== 修改状态1 =====");user.show();// 4. 修改状态2:更新手机号user.setPhone("13900139000");caretaker.saveMemento(user.createMemento());System.out.println("\n===== 修改状态2 =====");user.show();// 5. 修改状态3:更新年龄user.setAge(25);caretaker.saveMemento(user.createMemento());System.out.println("\n===== 修改状态3 =====");user.show();// 6. 第一次撤销:回到状态2System.out.println("\n===== 第一次撤销 =====");if (caretaker.canUndo()) {user.restoreMemento(caretaker.undo());user.show();}// 7. 第二次撤销:回到状态1System.out.println("\n===== 第二次撤销 =====");if (caretaker.canUndo()) {user.restoreMemento(caretaker.undo());user.show();}// 8. 第三次撤销:回到初始状态System.out.println("\n===== 第三次撤销 =====");if (caretaker.canUndo()) {user.restoreMemento(caretaker.undo());user.show();}// 9. 第四次撤销:无历史状态System.out.println("\n===== 第四次撤销 =====");caretaker.undo();}}
http://www.jsqmd.com/news/187243/

相关文章:

  • 投标文件编制提速:竞争性谈判中的时间优势获取
  • 多线程与SIMD加速,深度剖析C++物理引擎效率极限突破路径
  • 如何用C++打造百万级并发通信协议?资深架构师亲授6大关键技术
  • 2026年 发明专利权威推荐榜:高质量预审/PCT/优审全流程解析,助力创新保护与全球布局 - 品牌企业推荐师(官方)
  • 预算编制建议生成:资源配置合理性的论证材料
  • AI自动生成优质提示词全攻略
  • 2025年不容错过的医疗装修工程优质厂家盘点,快速卷帘门/净化工作台/医疗装修工程/FFU/净化工程/洁净棚医疗装修工程直销厂家排行 - 品牌推荐师
  • 12.3 实验二十一观察者模式 实验二十二状态模式 实验二十三策略模式
  • C++内存泄漏终极解决方案:99%工程师忽略的内核级防护机制
  • 电气自动化 基于plc的智能温室控制系统设计
  • 【独家披露】头部大厂AIGC延迟优化秘技:基于C++的零拷贝与异步调度方案
  • 实用指南:【RAG全栈】Task05:项目实战一
  • 朋友圈样式测试
  • 从初稿到定稿:论文 “避雷” 全攻略,藏在 paperxie 论文查重里的学术安全感
  • AI主播新闻播报:新闻资讯生产的自动化尝试
  • 2026年焊接机厂家权威推荐榜:米亚基/松下/UNITEK等电阻焊与热压焊接机品牌实力深度解析 - 品牌企业推荐师(官方)
  • 安全合规检查清单生成:风控体系数字化转型尝试
  • 从初稿到定稿:学术人必备的 “文字安检站”——paperxie 论文查重
  • 船舶导航系统抗干扰测试技术报告
  • OKR目标设定辅助:确保对齐与聚焦的管理工具
  • 成本控制措施列举:降本增效的具体实施方案
  • 抖音热门视频脚本:短平快内容创作的黄金公式
  • 企业文化宣传材料批量生产:价值观传播的新渠道
  • 文学作品改写尝试:不同难度等级的阅读版本生成
  • 论文图表不用愁:一键生成流程图 / 机制图的秘密藏在 paperxie 科研绘图里
  • IO多路复用 vs 异步通信,C++网络模块如何选择?
  • 如何利用C++26实现零开销std::future结果传递?专家级实践指南
  • 面试模拟问答训练:提前准备高频问题的应对策略
  • 仅限本周公开:C++量子计算高精度框架设计内部笔记(限时分享)
  • “课程论文赶稿” 的破局之道:不用熬夜凑字,这个工具让你 2 小时出成稿 ——paperxie 课程论文写作