11.30
实验201.类图
┌─────────────────┐
│ Caretaker │
├─────────────────┤
│ - history: Stack
│ - redoStack: Stack
├─────────────────┤
│ + saveState(Memento) │
│ + undo(): Memento │
│ + redo(): Memento │
│ + canUndo(): boolean │
│ + canRedo(): boolean │
└─────────────────┘
▲
│
│
┌─────────────────┐
│ Originator │
├─────────────────┤
│ - name: String │
│ - age: int │
│ - email: String │
├─────────────────┤
│ + saveToMemento(): Memento │
│ + restoreFromMemento(Memento) │
│ + setName(String) │
│ + setAge(int) │
│ + setEmail(String) │
│ + toString(): String │
└─────────────────┘
▲
│
│
┌─────────────────┐
│ Memento │
├─────────────────┤
│ - name: String │
│ - age: int │
│ - email: String │
├─────────────────┤
│ + getName(): String │
│ + getAge(): int │
│ + getEmail(): String │
└─────────────────┘
2.源代码
import java.util.Stack;
/**
-
用户信息管理器 - 支持多次撤销和重做功能
-
实现了备忘录模式,包含原发器、备忘录和管理者角色
*/
public class UserManager {// 备忘录类 - 存储用户状态快照
private static class UserMemento {
private final String name;
private final int age;
private final String email;/** * 构造函数 * @param name 用户名 * @param age 年龄 * @param email 邮箱 */ public UserMemento(String name, int age, String email) { this.name = name; this.age = age; this.email = email; } // Getter 方法 public String getName() { return name; } public int getAge() { return age; } public String getEmail() { return email; } @Override public String toString() { return String.format("UserMemento{name='%s', age=%d, email='%s'}", name, age, email); }}
// 原发器类 - 用户信息
private static class User {
private String name;
private int age;
private String email;/** * 构造函数 * @param name 用户名 * @param age 年龄 * @param email 邮箱 */ public User(String name, int age, String email) { this.name = name; this.age = age; this.email = email; } /** * 保存状态到备忘录 * @return 用户状态备忘录 */ public UserMemento saveToMemento() { return new UserMemento(name, age, email); } /** * 从备忘录恢复状态 * @param memento 用户状态备忘录 */ public void restoreFromMemento(UserMemento memento) { this.name = memento.getName(); this.age = memento.getAge(); this.email = memento.getEmail(); } // Setter 方法 public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return String.format("User{name='%s', age=%d, email='%s'}", name, age, email); }}
// 管理者类 - 负责管理备忘录
private static class Caretaker {
private final StackundoStack = new Stack<>();
private final StackredoStack = new Stack<>();
private static final int MAX_HISTORY_SIZE = 10; // 最大历史记录数/** * 保存状态 * @param memento 用户状态备忘录 */ public void saveState(UserMemento memento) { undoStack.push(memento); redoStack.clear(); // 新的操作后清空重做栈 // 限制历史记录数量,防止内存溢出 if (undoStack.size() > MAX_HISTORY_SIZE) { // 移除最旧的历史记录 Stack<UserMemento> temp = new Stack<>(); while (undoStack.size() > MAX_HISTORY_SIZE - 1) { temp.push(undoStack.pop()); } undoStack.clear(); while (!temp.isEmpty()) { undoStack.push(temp.pop()); } } } /** * 撤销操作 * @param currentState 当前状态 * @return 撤销后的状态 */ public UserMemento undo(UserMemento currentState) { if (canUndo()) { redoStack.push(currentState); return undoStack.pop(); } return currentState; } /** * 重做操作 * @param currentState 当前状态 * @return 重做后的状态 */ public UserMemento redo(UserMemento currentState) { if (canRedo()) { undoStack.push(currentState); return redoStack.pop(); } return currentState; } /** * 是否可以撤销 * @return 是否可以撤销 */ public boolean canUndo() { return !undoStack.isEmpty(); } /** * 是否可以重做 * @return 是否可以重做 */ public boolean canRedo() { return !redoStack.isEmpty(); } /** * 获取撤销栈大小 * @return 撤销栈大小 */ public int getUndoStackSize() { return undoStack.size(); } /** * 获取重做栈大小 * @return 重做栈大小 */ public int getRedoStackSize() { return redoStack.size(); }}
// 主程序 - 演示功能
public static void main(String[] args) {
// 创建用户
User user = new User("张三", 25, "zhangsan@email.com");
Caretaker caretaker = new Caretaker();System.out.println("=== 用户信息多次撤销演示系统 ==="); System.out.println("初始状态: " + user); System.out.println(); // 第一次修改并保存状态 caretaker.saveState(user.saveToMemento()); user.setName("李四"); user.setAge(30); System.out.println("第一次修改后: " + user); // 第二次修改并保存状态 caretaker.saveState(user.saveToMemento()); user.setEmail("lisi@newemail.com"); System.out.println("第二次修改后: " + user); // 第三次修改并保存状态 caretaker.saveState(user.saveToMemento()); user.setName("王五"); user.setAge(35); System.out.println("第三次修改后: " + user); System.out.println("\n=== 开始撤销操作 ==="); // 第一次撤销 if (caretaker.canUndo()) { UserMemento currentState = user.saveToMemento(); UserMemento previousState = caretaker.undo(currentState); user.restoreFromMemento(previousState); System.out.println("第一次撤销后: " + user); System.out.println("剩余可撤销次数: " + caretaker.getUndoStackSize()); } // 第二次撤销 if (caretaker.canUndo()) { UserMemento currentState = user.saveToMemento(); UserMemento previousState = caretaker.undo(currentState); user.restoreFromMemento(previousState); System.out.println("第二次撤销后: " + user); System.out.println("剩余可撤销次数: " + caretaker.getUndoStackSize()); } // 第三次撤销 if (caretaker.canUndo()) { UserMemento currentState = user.saveToMemento(); UserMemento previousState = caretaker.undo(currentState); user.restoreFromMemento(previousState); System.out.println("第三次撤销后: " + user); System.out.println("剩余可撤销次数: " + caretaker.getUndoStackSize()); } System.out.println("\n=== 开始重做操作 ==="); // 第一次重做 if (caretaker.canRedo()) { UserMemento currentState = user.saveToMemento(); UserMemento nextState = caretaker.redo(currentState); user.restoreFromMemento(nextState); System.out.println("第一次重做后: " + user); System.out.println("剩余可重做次数: " + caretaker.getRedoStackSize()); } // 第二次重做 if (caretaker.canRedo()) { UserMemento currentState = user.saveToMemento(); UserMemento nextState = caretaker.redo(currentState); user.restoreFromMemento(nextState); System.out.println("第二次重做后: " + user); System.out.println("剩余可重做次数: " + caretaker.getRedoStackSize()); } System.out.println("\n=== 最终状态 ==="); System.out.println("用户信息: " + user); System.out.println("可撤销次数: " + caretaker.getUndoStackSize()); System.out.println("可重做次数: " + caretaker.getRedoStackSize());}
}
3.运行结果

浙公网安备 33010602011771号