设计模式之备忘录模式

在日常开发中,我们经常会遇到这样的场景:需要保存对象的某个历史状态,以便将来恢复。这种需求最常见的例子就是"撤销操作"。在这种情况下,**备忘录模式(Memento Pattern)**就派上了用场。

目录

[1. 概念](#1. 概念)

[2. 代码实现](#2. 代码实现)

[3. 总结](#3. 总结)


1. 概念

备忘录模式属于行为型设计模式。它的核心思想是:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将对象恢复到原先保存的状态。

通俗点讲,备忘录模式就像是在玩游戏时存档:你保存了一个状态,之后可以随时"读档"回来。

备忘录模式包含三个关键角色:

  1. Originator(发起人):需要保存状态的对象

  2. Memento(备忘录):用来存储对象的内部状态

  3. Caretaker(管理者):负责保存备忘录,但不会操作或检查其内容

2. 代码实现

这里我将采用一个编辑/撤销文本的案例来实现备忘录模式。

首先我准备一个Editor类

java 复制代码
public class Editor {
    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.getText();
    }

    // 内部备忘录类
    public static class Memento {
        private final String text;

        private Memento(String text) {
            this.text = text;
        }

        private String getText() {
            return text;
        }
    }
}

这里我定义了一个静态内部类即Memento类,主要作为一个备忘录,也是被记录的状态类。

接下来再定义管理者,负责管理备忘录:

java 复制代码
import java.util.Stack;

public class History {
    private final Stack<Editor.Memento> history = new Stack<>();

    public void push(Editor.Memento memento) {
        history.push(memento);
    }

    public Editor.Memento pop() {
        if (!history.isEmpty()) {
            return history.pop();
        }
        return null;
    }
}

这里我们这个管理类也基于栈来实现,其后进先出的特性可以很好的实现我们需要的写入撤销的业务逻辑。

最后完成一个主测试类:

java 复制代码
public class MementoDemo {
    public static void main(String[] args) {
        Editor editor = new Editor();
        History history = new History();

        editor.setText("Version 1");
        history.push(editor.save());

        editor.setText("Version 2");
        history.push(editor.save());

        editor.setText("Version 3");
        System.out.println("当前内容: " + editor.getText()); // 输出 Version 3

        editor.restore(history.pop());
        System.out.println("撤销后: " + editor.getText()); // 输出 Version 2

        editor.restore(history.pop());
        System.out.println("再次撤销: " + editor.getText()); // 输出 Version 1
    }
}

3. 总结

备忘录模式的封装良好,但其实在实际工作中用到的地方并没有很多,绝大多数的游戏服务器实现存档的功能类似备忘录模式,但是对于后端服务器业务开发过程中,此设计模式的实践并不是很多,大家可以作为了解即可。

相关推荐
Zane19949 小时前
同一段单例代码,为什么在高并发下偶尔会创建出两个实例?聊聊哪种单例实现才是真的安全
设计模式
Carl_奕然9 小时前
【智能体】Loop 的四种设计模式之:Agent Loop(2026 最新版)
人工智能·设计模式·语言模型
小酒星小杜10 小时前
画 AI 漫画,别只会写“日漫风”:10 种画风、适用故事和可复制提示词
人工智能·设计模式·程序员
sarasuki21 小时前
为什么 Agent 工具需要一个「协议」而不是「框架」:MCP 成为标准的底层逻辑
设计模式·agent·mcp
vivo互联网技术21 小时前
知识不是文件,也不是向量 | KDC 系列 02
人工智能·设计模式·架构
Zane19947 天前
一个 new 就能创建对象,为什么还要拆出单例、工厂、建造者、原型四种模式?
设计模式
怕浪猫7 天前
一行命令复刻爆款视频,我把 Hypit 从安装跑到了出片
人工智能·设计模式·程序员
Zane19948 天前
函数式编程里的函数,其实不是你天天写的那个函数——三大编程范式的边界在哪
设计模式
Zane19949 天前
策略模式现在该不该上?一次讲清楚过度设计和设计不足怎么找平衡
设计模式
她说..9 天前
常见设计模式-模板方法模式
java·spring·设计模式·springboot