本文目录导读:

我将为您详细介绍备忘录模式的几个经典案例。
游戏存档系统(最典型)
这是备忘录模式最经典的应用场景。
// 备忘录:保存游戏状态
class GameMemento {
private int level;
private int score;
private int health;
private String position;
public GameMemento(int level, int score, int health, String position) {
this.level = level;
this.score = score;
this.health = health;
this.position = position;
}
// getters...
public int getLevel() { return level; }
public int getScore() { return score; }
public int getHealth() { return health; }
public String getPosition() { return position; }
}
// 发起人:游戏角色
class GamePlayer {
private int level = 1;
private int score = 0;
private int health = 100;
private String position = "起点";
public void play() {
level++;
score += 100;
health -= 10;
position = "关卡" + level;
System.out.println("游戏进行中... 等级:" + level +
" 分数:" + score + " 生命:" + health);
}
// 保存游戏状态
public GameMemento save() {
return new GameMemento(level, score, health, position);
}
// 恢复游戏状态
public void restore(GameMemento memento) {
this.level = memento.getLevel();
this.score = memento.getScore();
this.health = memento.getHealth();
this.position = memento.getPosition();
}
public void display() {
System.out.println("当前状态 - 等级:" + level +
" 分数:" + score + " 生命:" + health +
" 位置:" + position);
}
}
// 管理者:存档管理
class GameArchiveManager {
private Stack<GameMemento> saves = new Stack<>();
public void saveGame(GamePlayer player) {
saves.push(player.save());
System.out.println("游戏已存档");
}
public void loadLastSave(GamePlayer player) {
if (!saves.isEmpty()) {
player.restore(saves.pop());
System.out.println("读取最近存档");
} else {
System.out.println("无存档可读取");
}
}
}
// 测试代码
public class GameTest {
public static void main(String[] args) {
GamePlayer player = new GamePlayer();
GameArchiveManager manager = new GameArchiveManager();
// 游戏进程
player.play();
player.play();
manager.saveGame(player); // 存档点1
player.play();
player.play();
manager.saveGame(player); // 存档点2
player.play();
player.play();
// 游戏失败,加载最近存档
manager.loadLastSave(player);
player.display();
// 再次失败,加载更早的存档
manager.loadLastSave(player);
player.display();
}
}
文档编辑器撤销功能
// 备忘录:文档快照
class DocumentMemento {
private String content;
private String cursorPosition;
private Date timestamp;
public DocumentMemento(String content, String cursorPosition) {
this.content = content;
this.cursorPosition = cursorPosition;
this.timestamp = new Date();
}
public String getContent() { return content; }
public String getCursorPosition() { return cursorPosition; }
public Date getTimestamp() { return timestamp; }
}
// 发起人:文档编辑器
class TextEditor {
private String content = "";
private String clipboard = "";
private List<String> undoHistory = new ArrayList<>();
public void type(String text) {
content += text;
System.out.println("输入: " + text);
}
public void deleteLastChar() {
if (!content.isEmpty()) {
content = content.substring(0, content.length() - 1);
System.out.println("删除最后一个字符");
}
}
public void undo(DocumentMemento memento) {
this.content = memento.getContent();
System.out.println("撤销操作,恢复到: " + content);
}
public DocumentMemento save() {
return new DocumentMemento(content, cursorPosition());
}
public String cursorPosition() {
return "位置: " + content.length();
}
public void display() {
System.out.println("文档内容: " + content);
System.out.println("文档长度: " + content.length());
}
}
// 管理者:操作历史
class HistoryManager {
private Stack<DocumentMemento> undoStack = new Stack<>();
private Stack<DocumentMemento> redoStack = new Stack<>();
public void saveState(TextEditor editor) {
undoStack.push(editor.save());
redoStack.clear();
System.out.println("状态已保存");
}
public DocumentMemento undo() {
if (!undoStack.isEmpty()) {
DocumentMemento memento = undoStack.pop();
redoStack.push(memento);
return memento;
}
return null;
}
public DocumentMemento redo() {
if (!redoStack.isEmpty()) {
DocumentMemento memento = redoStack.pop();
undoStack.push(memento);
return memento;
}
return null;
}
}
// 测试代码
public class EditorTest {
public static void main(String[] args) {
TextEditor editor = new TextEditor();
HistoryManager history = new HistoryManager();
editor.type("Hello");
history.saveState(editor);
editor.type(" World");
history.saveState(editor);
editor.type("!");
history.saveState(editor);
// 执行撤销
DocumentMemento memento = history.undo();
if (memento != null) {
editor.undo(memento);
}
editor.display();
}
}
电商订单状态恢复
// 备忘录:订单状态
class OrderMemento {
private String status;
private double totalAmount;
private List<OrderItem> items;
private String shippingAddress;
private String paymentMethod;
public OrderMemento(String status, double totalAmount,
List<OrderItem> items, String address, String payment) {
this.status = status;
this.totalAmount = totalAmount;
this.items = new ArrayList<>(items);
this.shippingAddress = address;
this.paymentMethod = payment;
}
// getters...
public String getStatus() { return status; }
public double getTotalAmount() { return totalAmount; }
public List<OrderItem> getItems() { return items; }
public String getShippingAddress() { return shippingAddress; }
public String getPaymentMethod() { return paymentMethod; }
}
class OrderItem {
private String productName;
private int quantity;
private double price;
public OrderItem(String name, int qty, double price) {
this.productName = name;
this.quantity = qty;
this.price = price;
}
// getters, toString...
}
// 发起人:订单
class Order {
private String status = "新建";
private double totalAmount = 0;
private List<OrderItem> items = new ArrayList<>();
private String shippingAddress;
private String paymentMethod;
public void addItem(OrderItem item) {
items.add(item);
calculateTotal();
System.out.println("添加商品: " + item);
}
public void removeItem(OrderItem item) {
items.remove(item);
calculateTotal();
System.out.println("移除商品: " + item);
}
private void calculateTotal() {
totalAmount = items.stream()
.mapToDouble(i -> i.price * i.quantity)
.sum();
}
public void updateStatus(String status) {
this.status = status;
System.out.println("订单状态更新为: " + status);
}
public void setShippingAddress(String address) {
this.shippingAddress = address;
System.out.println("发货地址: " + address);
}
public void setPaymentMethod(String method) {
this.paymentMethod = method;
System.out.println("支付方式: " + method);
}
public OrderMemento saveState() {
return new OrderMemento(status, totalAmount, items,
shippingAddress, paymentMethod);
}
public void restoreState(OrderMemento memento) {
this.status = memento.getStatus();
this.totalAmount = memento.getTotalAmount();
this.items = memento.getItems();
this.shippingAddress = memento.getShippingAddress();
this.paymentMethod = memento.getPaymentMethod();
System.out.println("订单状态已恢复");
}
public void displayOrder() {
System.out.println("=== 订单详情 ===");
System.out.println("状态: " + status);
System.out.println("总金额: $" + String.format("%.2f", totalAmount));
System.out.println("商品列表: " + items);
System.out.println("发货地址: " + shippingAddress);
System.out.println("支付方式: " + paymentMethod);
}
}
// 管理者:订单历史记录
class OrderHistory {
private Map<String, OrderMemento> history = new HashMap<>();
public void save(Order order, String checkpoint) {
history.put(checkpoint, order.saveState());
System.out.println("订单检查点保存: " + checkpoint);
}
public void restore(Order order, String checkpoint) {
OrderMemento memento = history.get(checkpoint);
if (memento != null) {
order.restoreState(memento);
} else {
System.out.println("未找到检查点: " + checkpoint);
}
}
}
// 测试代码
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
OrderHistory history = new OrderHistory();
// 创建订单
order.addItem(new OrderItem("iPhone 15 Pro", 1, 999.99));
order.addItem(new OrderItem("AirPods Pro", 1, 249.99));
order.setShippingAddress("北京朝阳区");
order.setPaymentMethod("支付宝");
history.save(order, "初始状态");
// 添加更多商品
order.addItem(new OrderItem("MacBook Pro", 1, 1999.99));
order.updateStatus("待支付");
history.save(order, "添加MacBook后");
// 用户改变主意
order.removeItem(new OrderItem("MacBook Pro", 1, 1999.99));
order.updateStatus("待确认");
// 恢复到之前状态
history.restore(order, "添加MacBook后");
order.displayOrder();
// 或者恢复到最新状态
history.restore(order, "初始状态");
order.displayOrder();
}
}
数据库事务管理
// 备忘录:数据库状态快照
class DatabaseMemento {
private Map<String, String> records;
public DatabaseMemento(Map<String, String> records) {
this.records = new HashMap<>(records);
}
public Map<String, String> getRecords() {
return new HashMap<>(records);
}
}
// 发起人:数据库
class Database {
private Map<String, String> records = new HashMap<>();
public void insert(String key, String value) {
records.put(key, value);
System.out.println("插入数据: " + key + "=" + value);
}
public void update(String key, String value) {
if (records.containsKey(key)) {
records.put(key, value);
System.out.println("更新数据: " + key + "=" + value);
}
}
public String query(String key) {
return records.get(key);
}
public DatabaseMemento save() {
return new DatabaseMemento(records);
}
public void restore(DatabaseMemento memento) {
this.records = memento.getRecords();
System.out.println("数据库恢复完成");
}
public void displayRecords() {
System.out.println("当前数据库记录: " + records);
}
}
// 管理者:事务管理器
class TransactionManager {
private Stack<DatabaseMemento> transactionStack = new Stack<>();
private Database database;
public TransactionManager(Database database) {
this.database = database;
}
public void beginTransaction() {
transactionStack.push(database.save());
System.out.println("开启事务");
}
public void commit() {
transactionStack.pop();
System.out.println("提交事务");
}
public void rollback() {
if (!transactionStack.isEmpty()) {
database.restore(transactionStack.pop());
System.out.println("回滚事务");
}
}
}
// 测试代码
public class DatabaseTest {
public static void main(String[] args) {
Database database = new Database();
TransactionManager transaction = new TransactionManager(database);
// 开始事务
transaction.beginTransaction();
database.insert("user1", "张三");
database.insert("user2", "李四");
database.displayRecords();
// 事务中操作
database.update("user1", "张三丰");
database.insert("user3", "王五");
database.displayRecords();
// 操作失误,回滚
transaction.rollback();
database.displayRecords();
// 重新操作
transaction.beginTransaction();
database.insert("user4", "赵六");
database.displayRecords();
transaction.commit();
}
}
这些案例展示了备忘录模式的核心价值:
- 状态保存与恢复:能够完整保存对象状态并在需要时恢复
- 封装性:发起人内部状态不对外暴露,由管理者统一管理
- 多级回退:通过栈结构支持多级撤销操作
- 检查点机制:在关键节点保存状态,便于回退
适用场景:
- 需要保存/恢复数据的场景(游戏存档)
- 需要撤销/重做功能的场景(文本编辑器)
- 数据库事务管理
- 版本控制等