揭秘备忘录模式:打造灵活高效的状态管理解决方案

备忘录模式(Memento Pattern)是一种行为设计模式,它允许在不暴露对象内部状态的情况下捕获和恢复对象的内部状态。这种模式主要用于实现撤销操作。

在 Java 中,备忘录模式通常包括以下三个角色:

发起人(Originator):负责创建一个备忘录对象,用于存储其内部状态,并可以恢复之前的状态。
备忘录(Memento):负责存储发起人的内部状态。
管理者(Caretaker):负责保存和提供备忘录对象。
如下图:
在这里插入图片描述
以上的uml类图的示例代码:

// 发起人
public class Originator {
   
    private String state;

    public void setState(String state) {
   
        this.state = state;
    }

    public String getState() {
   
        return state;
    }

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

    public void restoreStateFromMemento(Memento memento) {
   
        state = memento.getState();
    }
}

// 备忘录
public class Memento {
   
    private String state;

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

    public String getState() {
   
        return state;
    }
}

// 管理者
public class Caretaker {
   
    private List<Memento> mementos = new ArrayList<>();

    public void addMemento(Memento memento) {
   
        mementos.add(memento);
    }

    public Memento getMemento(int index) {
   
        return mementos.get(index);
    }
}

使用示例:

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

        originator.setState("状态1");
        System.out.println("当前状态: " + originator.getState());
        caretaker.addMemento(originator.saveStateToMemento());

        originator.setState("状态2");
        System.out.println("当前状态: " + originator.getState());
        caretaker.addMemento(originator.saveStateToMemento());

        originator.setState("状态3");
        System.out.println("当前状态: " + originator.getState());
        caretaker.addMemento(originator.saveStateToMemento());

        // 恢复到状态2
        originator.restoreStateFromMemento(caretaker.getMemento(1));
        System.out.println("恢复到状态2: " + originator.getState());
    }
}

以下是一些适用备忘录模式的场景:

  • 实现撤销操作:在文本编辑器如Word中,用户可能需要撤销之前的输入或删除操作,备忘录模式可以用来保存每一步的编辑状态,使得用户能够通过Ctrl + Z来撤销操作。
  • 实现对象的历史记录功能:在需要记录对象历史状态的应用中,如游戏中的存档功能,备忘录模式可以用来保存游戏进度,允许玩家在稍后的时间点加载之前的游戏状态。
  • 保护对象封装性:当需要保存和恢复对象的状态,但又不希望暴露对象的内部实现细节时,备忘录模式提供了一种方式,可以在不破坏对象封装性的前提下进行状态管理。

总的来说,备忘录模式提供了一种灵活的方式来管理对象的状态,它允许对象在不暴露内部实现的情况下,保存和恢复其状态,这在很多应用程序中都是非常有用的。

优点:

  • 封装性良好:备忘录模式将状态保存和恢复的逻辑封装在备忘录对象中,使得客户端无需了解对象的内部实现细节。
  • 可撤销操作:提供了一种可以恢复到之前状态的机制,这在需要支持撤销操作的场景中非常有用。
  • 性能开销小:由于备忘录模式只存储对象的状态,而不是整个对象,因此在空间和时间上的开销较小。

缺点:

  • 占用额外空间:每个备忘录都会占用额外的内存空间来存储状态信息,如果备忘录的数量很多,可能会占用大量内存。
  • 维护成本:当原发器的状态结构发生变化时,可能需要修改备忘录类的相关代码,增加了维护成本。
  • 使用限制:备忘录模式通常要求原发器类具有较为简单的内部状态,如果内部状态非常复杂或者难以序列化,那么使用备忘录模式可能会变得困难。

与其他模式的关系

备忘录模式通常与行为型模式中的其他模式结合使用,以实现更复杂的功能。以下是一些备忘录模式与其他设计模式的运用方式:

  1. 与命令模式(Command Pattern)结合:命令模式用于将操作封装为对象,这样可以根据需要存储、传递和执行这些操作。在实现撤销功能时,可以结合使用备忘录模式和命令模式。当执行一个命令时,可以先创建一个备忘录来保存当前状态,然后再执行命令。如果需要撤销,可以从备忘录中恢复状态。
  2. 与原型模式(Prototype Pattern)结合:原型模式用于通过复制现有的实例来创建新的实例,而不是通过调用构造函数。在需要保存和恢复状态的场景中,可以使用原型模式来创建备忘录对象,这样可以避免每次都重新初始化备忘录对象。
  3. 与访问者模式(Visitor Pattern)结合:访问者模式允许在不修改类结构的情况下添加新的操作。当需要对备忘录对象进行不同的操作时,可以使用访问者模式来实现这些操作,而不需要修改备忘录对象的内部结构。
  4. 与单例模式(Singleton Pattern)结合:单例模式确保一个类只有一个实例,并提供一个全局访问点。在备忘录模式中,管理者(Caretaker)角色可以使用单例模式来实现,以确保整个系统中只有一个管理者负责备忘录的保存和恢复。
  5. 与工厂方法模式(Factory Method Pattern)结合:工厂方法模式用于创建一个对象的接口,让子类决定实例化哪一个类。在创建备忘录对象时,可以使用工厂方法模式来生成不同类型的备忘录,以便根据不同的需求保存不同的状态信息。
  6. 与策略模式(Strategy Pattern)结合:策略模式定义了一系列算法,并将每个算法封装起来,使它们可以互换。在恢复备忘录的状态时,可以使用策略模式来选择不同的恢复策略,例如根据用户的偏好或者系统的性能要求来选择不同的恢复方式。

最近更新

  1. TCP协议是安全的吗?

    2024-02-05 05:32:01       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-05 05:32:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-05 05:32:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-05 05:32:01       20 阅读

热门阅读

  1. docker

    2024-02-05 05:32:01       32 阅读
  2. 数据库事务隔离级别

    2024-02-05 05:32:01       29 阅读
  3. vue基本理解

    2024-02-05 05:32:01       29 阅读
  4. 分组函数应用(sql+python)总结

    2024-02-05 05:32:01       32 阅读
  5. MySQL中如何将字符串替换

    2024-02-05 05:32:01       34 阅读
  6. hadoop使用公平调度器

    2024-02-05 05:32:01       30 阅读
  7. 面试 CSS 框架八股文十问十答第五期

    2024-02-05 05:32:01       33 阅读
  8. 深度解析Go字符串

    2024-02-05 05:32:01       24 阅读
  9. 前端Vue every() 方法

    2024-02-05 05:32:01       33 阅读
  10. 【力扣经典面试题】45. 跳跃游戏 II

    2024-02-05 05:32:01       34 阅读
  11. C++多态

    C++多态

    2024-02-05 05:32:01      31 阅读
  12. 记录 | python .ui转py

    2024-02-05 05:32:01       27 阅读
  13. 【深度学习】P1 Deep Learning 简介

    2024-02-05 05:32:01       34 阅读