备忘录模式

备忘录模式(Memento Pattern)是一种行为型设计模式,用于在不破坏对象封装性的前提下,捕获并保存一个对象的内部状态,以便在需要时恢复到该状态。它常用于需要实现撤销(undo)或恢复(restore)功能的情景,比如文本编辑器的撤销操作、游戏存档等。

备忘录模式的组成

备忘录模式通常包含以下几个角色:

  1. 发起人(Originator):需要保存状态的对象。它负责创建备忘录(存储当前状态)并在需要时使用备忘录恢复状态。
  2. 备忘录(Memento):存储发起人内部状态的对象。通常只提供有限的访问接口(如只允许发起人访问其状态)。
  3. 管理者(Caretaker):负责保存备忘录,但不操作或检查备忘录的内容。它只负责传递和存储备忘录。

工作原理

  1. 发起人创建一个备忘录,保存当前状态。
  2. 管理者接收并存储这个备忘录。
  3. 当需要恢复状态时,发起人从管理者获取备忘录,并用其恢复到之前的状态。

UML 类图

┌────────────────┐       ┌────────────────┐       ┌────────────────┐
│   Originator   │       │    Memento     │       │   Caretaker    │
├────────────────┤       ├────────────────┤       ├────────────────┤
│ state          │<----->│ state          │       │ mementoList    │
│ createMemento()│       │ getState()     │       │ addMemento()   │
│ setMemento()   │       │ setState()     │       │ getMemento()   │
└────────────────┘       └────────────────┘       └────────────────┘

代码示例(以 Java 为例)

以下是一个简单的备忘录模式实现,模拟文本编辑器的撤销功能:

// 备忘录类,存储状态
class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }
}

// 发起人类,管理状态并创建/恢复备忘录
class Originator {
    private String state;

    public void setState(String state) {
        this.state = state;
        System.out.println("当前状态: " + state);
    }

    public String getState() {
        return state;
    }

    public Memento createMemento() {
        return new Memento(state);
    }

    public void setMemento(Memento memento) {
        state = memento.getState();
        System.out.println("恢复状态到: " + state);
    }
}

// 管理者类,负责存储备忘录
class Caretaker {
    private Memento memento;

    public void setMemento(Memento memento) {
        this.memento = memento;
    }

    public Memento getMemento() {
        return memento;
    }
}

// 测试代码
public class Main {
    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();

        // 设置初始状态
        originator.setState("状态1");
        // 保存状态到备忘录
        caretaker.setMemento(originator.createMemento());

        // 修改状态
        originator.setState("状态2");

        // 恢复之前的状态
        originator.setMemento(caretaker.getMemento());
    }
}

输出:

当前状态: 状态1
当前状态: 状态2
恢复状态到: 状态1

备忘录模式的特点

  • 优点
  • 提供了一种状态恢复机制,适合需要撤销或回滚的场景。
  • 保持封装性,备忘录的内部状态对外部对象不可见。
  • 缺点
  • 如果状态数据量大,保存备忘录可能消耗较多内存。
  • 增加了系统的复杂性,需要额外管理备忘录对象。

使用场景

  1. 需要保存和恢复对象状态的场景,如:
  • 文本编辑器的撤销功能。
  • 游戏中的存档和读档。
  • 数据库事务的回滚。
  1. 需要在不破坏对象封装性的情况下保存状态。

注意事项

  • 备忘录的访问权限需要严格控制,通常只允许发起人访问其内部状态。
  • 如果需要保存多个状态点,可以在管理者中使用列表(如 List<Memento>)来存储多个备忘录。
  • 在实际应用中,可以结合其他模式(如命令模式)实现更复杂的撤销/重做功能。

总结

备忘录模式通过分离状态保存与恢复的职责,实现了状态的外部化管理,同时保护了对象的封装性。它在需要历史状态管理的场景中非常实用,尤其适合实现撤销功能或状态回溯的系统。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注