备忘录模式(Memento Pattern)

备忘录模式(Memento Pattern)

备忘录模式是一种行为型设计模式,它允许在不暴露对象实现细节的情况下保存和恢复对象的先前状态。备忘录模式通过将对象的状态封装到一个备忘录对象中,使得对象可以在需要时恢复到之前的状态。

模式结构

  1. 发起者类(Originator)
    负责创建一个备忘录对象,用以记录当前的内部状态,并可以使用备忘录恢复内部状态。
  2. 备忘录类(Memento)
    负责存储发起者对象的内部状态,并可防止发起者以外的其他对象访问备忘录。
  3. 管理者类(Caretaker)
    负责保存备忘录对象,但不能对备忘录的内容进行操作或检查。

代码示例

1. 发起者类(Originator)

// 发起者类:负责创建备忘录并恢复状态
class FileWriter {
    private String fileName;
    private StringBuilder content;

    public FileWriter(String fileName) {
        this.fileName = fileName;
        this.content = new StringBuilder();
    }

    // 写入内容
    public void write(String string) {
        content.append(string);
    }

    // 保存当前状态到备忘录
    public Memento save() {
        return new Memento(this.fileName, this.content);
    }

    // 恢复到备忘录中的状态
    public void undoToLastSave(Memento memento) {
        this.fileName = memento.getFileName();
        this.content = memento.getContent();
    }

    @Override
    public String toString() {
        return content.toString();
    }
}

2. 备忘录类(Memento)

// 备忘录类:存储发起者对象的状态
class Memento {
    private final String fileName;
    private final StringBuilder content;

    public Memento(String fileName, StringBuilder content) {
        this.fileName = fileName;
        this.content = new StringBuilder(content);
    }

    public String getFileName() {
        return fileName;
    }

    public StringBuilder getContent() {
        return content;
    }
}

3. 管理者类(Caretaker)

// 管理者类:负责保存备忘录对象
class FileCaretaker {
    private Memento memento;

    // 保存备忘录
    public void save(FileWriter writer) {
        this.memento = writer.save();
    }

    // 恢复到备忘录中的状态
    public void undo(FileWriter writer) {
        writer.undoToLastSave(memento);
    }
}

4. 调用示例

public class MementoPattern {
    public static void main(String[] args) {
        FileCaretaker caretaker = new FileCaretaker();

        FileWriter writer = new FileWriter("data.txt");
        writer.write("First Set of Data \n");
        System.out.println(writer);

        // 保存当前状态
        caretaker.save(writer);
        writer.write("Second Set of Data \n");
        System.out.println(writer);

        // 恢复到之前的状态
        caretaker.undo(writer);
        System.out.println(writer);
    }
}

输出结果

First Set of Data 

First Set of Data 
Second Set of Data 

First Set of Data 

应用场景

  1. 撤销操作
    当需要实现撤销操作时,可以使用备忘录模式来保存对象的状态,并在需要时恢复到之前的状态。
  2. 状态历史记录
    当需要维护或记录对象的状态历史时,可以使用备忘录模式。备忘录模式允许保存对象的状态快照,并在需要时恢复。
  3. 保护对象状态
    当需要保护对象的状态不被外部访问时,可以使用备忘录模式。备忘录模式将对象的状态封装在备忘录对象中,防止外部直接访问。

在Java中的应用

  • java.io.Serializable
    Java 的序列化机制可以看作是一种备忘录模式的实现。通过序列化,可以将对象的状态保存到文件中,并在需要时反序列化恢复对象的状态。

优缺点

优点

  1. 保护对象状态
    备忘录模式可以在不破坏对象封装的情况下保存对象的状态,保护了对象状态的完整性。
  2. 支持撤销操作
    备忘录模式允许保存对象的状态快照,从而支持撤销操作。
  3. 简化发起者类
    备忘录模式将状态保存和恢复的逻辑从发起者类中分离出来,简化了发起者类的代码。

缺点

  1. 内存消耗
    如果频繁地创建备忘录对象,可能会导致内存消耗过大。
  2. 管理者类的复杂性
    管理者类需要负责跟踪备忘录对象的生命周期,增加了系统的复杂性。

总结

备忘录模式通过将对象的状态封装到备忘录对象中,使得对象可以在需要时恢复到之前的状态。它适用于需要实现撤销操作、维护状态历史记录或保护对象状态的场景。尽管它可能会增加内存消耗和管理者类的复杂性,但其优点在于提高了系统的灵活性和可维护性。在Java中,备忘录模式广泛应用于序列化和状态管理等场景。