Java备忘录模式详解

打印 上一主题 下一主题

主题 1696|帖子 1696|积分 5088

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
备忘录模式详解

一、备忘录模式概述

备忘录模式(Memento Pattern)是一种行为型设计模式,它答应在不破坏封装性的条件下捕捉并外部化一个对象的内部状态,以便以后可以将该对象恢复到原先保存的状态。
核心特点



  • 状态保存:捕捉对象内部状态
  • 封装掩护:不暴露对象实现细节
  • 打消机制:支持回滚到之前状态
  • 汗青管理:可维护多个状态快照
二、备忘录模式的结构

主要脚色


  • Originator:原发器,需要保存状态的对象
  • Memento:备忘录,存储原发器状态
  • Caretaker:管理者,负责保存和恢复备忘录
三、备忘录模式的实现

1. 基本实现

  1. // 备忘录类
  2. public class TextMemento {
  3.     private final String text;
  4.    
  5.     public TextMemento(String text) {
  6.         this.text = text;
  7.     }
  8.    
  9.     public String getText() {
  10.         return text;
  11.     }
  12. }
  13. // 原发器 - 文本编辑器
  14. public class TextEditor {
  15.     private String text;
  16.    
  17.     public void write(String text) {
  18.         this.text = text;
  19.     }
  20.    
  21.     public TextMemento save() {
  22.         return new TextMemento(text);
  23.     }
  24.    
  25.     public void restore(TextMemento memento) {
  26.         this.text = memento.getText();
  27.     }
  28.    
  29.     public void print() {
  30.         System.out.println("当前内容: " + text);
  31.     }
  32. }
  33. // 管理者
  34. public class History {
  35.     private Stack<TextMemento> history = new Stack<>();
  36.    
  37.     public void push(TextMemento memento) {
  38.         history.push(memento);
  39.     }
  40.    
  41.     public TextMemento pop() {
  42.         return history.pop();
  43.     }
  44. }
  45. // 使用示例
  46. TextEditor editor = new TextEditor();
  47. History history = new History();
  48. editor.write("第一版内容");
  49. history.push(editor.save());
  50. editor.print();
  51. editor.write("修改后的内容");
  52. editor.print();
  53. editor.restore(history.pop());
  54. editor.print(); // 恢复为"第一版内容"
复制代码
2. 更复杂的实现(支持多个属性)

  1. // 游戏角色状态
  2. public class GameCharacter {
  3.     private int level;
  4.     private int health;
  5.     private String location;
  6.    
  7.     public GameCharacter(int level, int health, String location) {
  8.         this.level = level;
  9.         this.health = health;
  10.         this.location = location;
  11.     }
  12.    
  13.     // 创建备忘录
  14.     public CharacterMemento save() {
  15.         return new CharacterMemento(level, health, location);
  16.     }
  17.    
  18.     // 从备忘录恢复
  19.     public void restore(CharacterMemento memento) {
  20.         this.level = memento.getLevel();
  21.         this.health = memento.getHealth();
  22.         this.location = memento.getLocation();
  23.     }
  24.    
  25.     // 其他方法...
  26. }
  27. // 角色备忘录
  28. public class CharacterMemento {
  29.     private final int level;
  30.     private final int health;
  31.     private final String location;
  32.    
  33.     public CharacterMemento(int level, int health, String location) {
  34.         this.level = level;
  35.         this.health = health;
  36.         this.location = location;
  37.     }
  38.    
  39.     // getter方法
  40.     public int getLevel() { return level; }
  41.     public int getHealth() { return health; }
  42.     public String getLocation() { return location; }
  43. }
复制代码
四、备忘录模式的应用场景

1. 文本编辑器打消功能

  1. public class AdvancedTextEditor {
  2.     private StringBuilder content;
  3.     private int cursorPosition;
  4.    
  5.     public AdvancedTextEditor() {
  6.         content = new StringBuilder();
  7.         cursorPosition = 0;
  8.     }
  9.    
  10.     public EditorState saveState() {
  11.         return new EditorState(content.toString(), cursorPosition);
  12.     }
  13.    
  14.     public void restoreState(EditorState state) {
  15.         this.content = new StringBuilder(state.getContent());
  16.         this.cursorPosition = state.getCursorPosition();
  17.     }
  18.    
  19.     // 其他编辑方法...
  20. }
  21. public class EditorState {
  22.     private final String content;
  23.     private final int cursorPosition;
  24.    
  25.     public EditorState(String content, int cursorPosition) {
  26.         this.content = content;
  27.         this.cursorPosition = cursorPosition;
  28.     }
  29.    
  30.     // getter方法...
  31. }
复制代码
2. 游戏存档体系

  1. public class GameSaveManager {
  2.     private List<GameSave> savePoints = new ArrayList<>();
  3.    
  4.     public void saveGame(GameWorld world) {
  5.         savePoints.add(world.createSave());
  6.     }
  7.    
  8.     public void loadGame(GameWorld world, int index) {
  9.         if (index >= 0 && index < savePoints.size()) {
  10.             world.restoreFromSave(savePoints.get(index));
  11.         }
  12.     }
  13. }
  14. public class GameWorld {
  15.     private String worldState;
  16.     private PlayerState playerState;
  17.    
  18.     public GameSave createSave() {
  19.         return new GameSave(worldState, playerState);
  20.     }
  21.    
  22.     public void restoreFromSave(GameSave save) {
  23.         this.worldState = save.getWorldState();
  24.         this.playerState = save.getPlayerState();
  25.     }
  26. }
复制代码
3. 事务回滚机制

  1. public class DatabaseTransaction {
  2.     private List<DatabaseMemento> mementos = new ArrayList<>();
  3.     private Database database;
  4.    
  5.     public void begin() {
  6.         mementos.add(database.createMemento());
  7.     }
  8.    
  9.     public void commit() {
  10.         mementos.clear();
  11.     }
  12.    
  13.     public void rollback() {
  14.         if (!mementos.isEmpty()) {
  15.             database.restoreFromMemento(mementos.get(mementos.size() - 1));
  16.             mementos.remove(mementos.size() - 1);
  17.         }
  18.     }
  19. }
复制代码
五、备忘录模式的变体

1. 增量备忘录

  1. public class IncrementalMemento {
  2.     private final Object deltaState; // 只存储变化的部分
  3.    
  4.     public IncrementalMemento(Object delta) {
  5.         this.deltaState = delta;
  6.     }
  7. }
复制代码
2. 序列化备忘录

  1. import java.io.*;
  2. public class SerializationMemento {
  3.     public static byte[] serialize(Object obj) throws IOException {
  4.         ByteArrayOutputStream bos = new ByteArrayOutputStream();
  5.         ObjectOutputStream oos = new ObjectOutputStream(bos);
  6.         oos.writeObject(obj);
  7.         return bos.toByteArray();
  8.     }
  9.    
  10.     public static Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
  11.         ByteArrayInputStream bis = new ByteArrayInputStream(data);
  12.         ObjectInputStream ois = new ObjectInputStream(bis);
  13.         return ois.readObject();
  14.     }
  15. }
复制代码
六、备忘录模式的优缺点

优点


  • 状态封装:不暴露对象内部细节
  • 简化原发器:状态保存恢复逻辑分离
  • 时间点恢复:可恢复到任意保存点
  • 快照管理:可维护多个状态版本
缺点


  • 内存消耗:保存多个状态大概占用大量内存
  • 性能影响:频繁保存状态大概影响性能
  • 实现复杂:部门对象状态大概难以捕捉
七、最佳实践


  • 公道控制快照数目:制止保存过多状态
  • 增量保存:只保存变化的部门
  • 考虑序列化:对于复杂对象使用序列化
  • 清算机制:定期清算逾期备忘录
  • 访问控制:限制对备忘录内部状态的访问
八、总结

备忘录模式是状态管理的有用方案,特别适用于:


  • 需要提供打消/重做功能
  • 需要保存对象汗青状态
  • 需要实现事务回滚机制
  • 需要保存体系快照
在实际开辟中,备忘录模式常见于:


  • 文本/图像编辑软件
  • 游戏存档体系
  • 数据库事务管理
  • 体系设置管理
  • 工作流状态保存
正确使用备忘录模式可以实现机动的状态管理,但需要注意内存和性能方面的考量。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万万哇

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表