侧边栏壁纸
博主头像
拾荒的小海螺博主等级

只有想不到的,没有做不到的

  • 累计撰写 224 篇文章
  • 累计创建 19 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

JAVA:备忘录模式(Memento Pattern)的技术指南

拾荒的小海螺
2025-03-31 / 0 评论 / 0 点赞 / 15 阅读 / 5921 字

1、简述

备忘录模式是一种行为型设计模式,旨在在不破坏封装的前提下,捕获并保存对象的当前状态,以便之后能恢复到这个状态。它为实现撤销和恢复操作提供了优雅的解决方案。

设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git

本文将详细介绍备忘录模式的概念、结构、优缺点以及实际应用案例。

image-iouv.png


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、总结

备忘录模式为状态的保存与恢复提供了一个优雅的解决方案,尤其适用于需要实现撤销/重做或多状态管理的场景。通过灵活运用备忘录模式,可以提升系统的可靠性和用户体验。

希望本文对您理解和应用备忘录模式有所帮助!欢迎交流讨论!

0

评论区