1 解决的问题

解决备份恢复的问题。

2 备忘录模式

在 ** 不违背封装原则 ** 的前提下,** 捕获一个对象的内部状态 **,并在该对象之外保存这个状态,一遍之后 ** 恢复 ** 对象为先前的状态。主要用于 防丢失撤销恢复 等。

3 实现代码

下面这里也可以增加一个备份管理类,用于存储与管理多份备份。

新建备忘录类:

class Memento {
    int life;
    int magic;
 
    Memento(int life, int magic) {
        this.life = life;
        this.magic = magic;
    }
}

玩家类中,通过备忘录类实现存档、读档:

class Player {
    ...
 
    // 存档
    public Memento saveState() {
        return new Memento(life, magic);
    }
 
    // 读档
    public void restoreState(Memento memento) {
        this.life = memento.life;
        this.magic = memento.magic;
    }
}

客户端类对应修改如下:

public class Client {
    @Test
    public void test() {
        Player player = new Player();
        // 存档
        Memento memento = player.saveState();
 
        // 打 Boss,打不过,壮烈牺牲
        player.fightBoss();
 
        // 读档
        player.restoreState(memento);
    }
}

4 优缺点

优点

  • 提供一种恢复机制,方便用户可以恢复到历史的某个状态
  • 实现了恢复过程的封装,用户不需要知道具体恢复过程是如何进行的

缺点

  • 耗费资源。备份内容多的话,占用系统资源 & 占用内存来备份。
  • 绝大部分动态编程语言 (例如 PHP、 Python 和 JavaScript) 不能确保备忘录中的状态不被修改。

5 应用场景

  • 需要保存一个对象在某个时刻的状态,以便后续撤销恢复,而又不希望外界直接访问对象的内部状态;

6 经典应用例子

IDE 设置的导入导出,VSCode 提供插件的导入导出配置。

低频率全量备份高频率增量备份,Git 的版本管理就是一个很好的例子:
Git 版本管理机制