1、简述
备忘录模式是一种行为型设计模式,旨在在不破坏封装的前提下,捕获并保存对象的当前状态,以便之后能恢复到这个状态。它为实现撤销和恢复操作提供了优雅的解决方案。
设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git
本文将详细介绍备忘录模式的概念、结构、优缺点以及实际应用案例。

2、什么是备忘录模式?
备忘录模式的核心思想是:通过保存对象的状态快照,允许对象恢复到之前的某个状态。备忘录模式在实现撤销操作、事务回滚等功能时非常有用。
典型应用场景包括:
🔹 文本编辑器的撤销功能。
🔹 游戏存档和加载。
🔹 数据库事务的回滚。
备忘录模式包含以下角色:
🔹 原发器(Originator):需要保存状态的对象。
🔹 备忘录(Memento):存储原发器的内部状态。
🔹 负责人(Caretaker):负责保存和恢复备忘录。
类图如下:
Originator <--> Memento <---> Caretaker
3. 实际案例
假设我们需要实现一个简单的文本编辑器,支持文本输入和撤销操作。
// 备忘录类
public class Memento {
    private final String state;
    public Memento(String state) {
        this.state = state;
    }
    public String getState() {
        return state;
    }
}
// 原发器类
public class TextEditor {
    private String text;
    public void setText(String text) {
        this.text = text;
    }
    public String getText() {
        return text;
    }
    public Memento save() {
        return new Memento(text);
    }
    public void restore(Memento memento) {
        this.text = memento.getState();
    }
}
// 负责人类
public class Caretaker {
    private final Stack<Memento> history = new Stack<>();
    public void save(Memento memento) {
        history.push(memento);
    }
    public Memento undo() {
        if (!history.isEmpty()) {
            return history.pop();
        }
        return null;
    }
}
// 测试类
public class MementoPatternDemo {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        Caretaker caretaker = new Caretaker();
        // 输入文本并保存状态
        editor.setText("Hello, World!");
        caretaker.save(editor.save());
        editor.setText("Hello, Design Patterns!");
        caretaker.save(editor.save());
        editor.setText("Hello, Memento Pattern!");
        System.out.println("当前文本: " + editor.getText());
        // 撤销一次
        editor.restore(caretaker.undo());
        System.out.println("撤销后文本: " + editor.getText());
        // 再撤销一次
        editor.restore(caretaker.undo());
        System.out.println("再次撤销后文本: " + editor.getText());
    }
}
输出:
当前文本: Hello, Memento Pattern!
撤销后文本: Hello, Design Patterns!
再次撤销后文本: Hello, World!
4、备忘录模式的高级应用
在游戏开发中,备忘录模式常用于实现游戏存档和加载功能。以下是一个简单示例:
public class GameState {
    private int level;
    private int score;
    public GameState(int level, int score) {
        this.level = level;
        this.score = score;
    }
    public int getLevel() {
        return level;
    }
    public int getScore() {
        return score;
    }
}
public class Game {
    private int level;
    private int score;
    public void play(int level, int score) {
        this.level = level;
        this.score = score;
    }
    public GameState save() {
        return new GameState(level, score);
    }
    public void load(GameState state) {
        this.level = state.getLevel();
        this.score = state.getScore();
    }
    public void showState() {
        System.out.println("Level: " + level + ", Score: " + score);
    }
}
public class GameDemo {
    public static void main(String[] args) {
        Game game = new Game();
        game.play(1, 100);
        GameState save1 = game.save();
        game.play(2, 200);
        GameState save2 = game.save();
        game.play(3, 300);
        game.showState(); // 当前状态
        game.load(save2); // 恢复到存档2
        game.showState();
        game.load(save1); // 恢复到存档1
        game.showState();
    }
}
输出:
Level: 3, Score: 300
Level: 2, Score: 200
Level: 1, Score: 100
5、备忘录模式的优缺点
优点
🔹  封装性:不需要暴露对象的内部状态即可保存和恢复。
🔹 易于扩展:支持撤销和恢复功能。
🔹 灵活性强:可以保存多个状态并在不同时间点恢复。
缺点
🔹 内存开销:如果状态对象较大或保存次数频繁,可能会占用大量内存。
🔹 实现复杂:实现过程中需要考虑状态存储的管理。
6、应用场景
🔹  撤销/重做功能:如文本编辑器、IDE。
🔹 游戏存档:如角色扮演游戏中的存档和加载。
🔹 事务回滚:如数据库事务。
7、总结
备忘录模式为状态的保存与恢复提供了一个优雅的解决方案,尤其适用于需要实现撤销/重做或多状态管理的场景。通过灵活运用备忘录模式,可以提升系统的可靠性和用户体验。
希望本文对您理解和应用备忘录模式有所帮助!欢迎交流讨论!