23种设计模式之备忘录模式

目录

  • [1. 简介](#1. 简介)
  • [2. 代码](#2. 代码)
    • [2.1 Order (原发器类)](#2.1 Order (原发器类))
    • [2.2 Memento (备忘录类)](#2.2 Memento (备忘录类))
    • [2.3 Container (负责人类)](#2.3 Container (负责人类))
    • [2.4 Test (测试)](#2.4 Test (测试))
    • [2.5 运行结果](#2.5 运行结果)
  • [3. 使用场景](#3. 使用场景)
  • [4. 优缺点](#4. 优缺点)
  • [5. 总结](#5. 总结)

1. 简介

备忘录模式(Memento Pattern) 是一种行为设计模式,它允许在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后可以将对象恢复到之前保存的状态。

例如,在文本编辑器软件中,用户可能会进行一系列的编辑操作,如输入文字、删除段落等。备忘录模式可以用来保存文本编辑器在各个操作阶段的状态,当用户想要撤销操作时,就可以利用保存的备忘录将文本恢复到之前的某个状态。

结构:

  • 原发器(Originator)类
    原发器是需要保存状态的对象,它创建备忘录对象并将自身状态存储在备忘录中,也可以从备忘录中恢复状态。
  • 备忘录(Memento)类
    备忘录用于存储原发器的状态。它是一个内部状态的存储载体,除了原发器本身外,其他对象不能直接访问备忘录的内部状态。
  • 负责人(Caretaker)类
    负责人负责保存备忘录对象,但不能对备忘录的内容进行修改或访问。它主要的职责是管理备忘录,如存储和提供备忘录给原发器进行状态恢复。

2. 代码

2.1 Order (原发器类)

java 复制代码
public class Order {
    private String state;

    public String getState() {
        return state;
    }

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

2.2 Memento (备忘录类)

java 复制代码
public class Memento {
    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
    public Order saveStateToOrder(){
        return new Order(state);
    }

    public void getStateFromOrder(Order order){
        state = order.getState();
    }
}

2.3 Container (负责人类)

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class Container {
     private List<Order> orderList = new ArrayList<>();

     public void addOrder(Order order){
         orderList.add(order);
     }
     public Order getOrder(int index){
         return orderList.get(index);
     }
}

2.4 Test (测试)

java 复制代码
public class Test {
    public static void main(String[] args) {
        Memento memento = new Memento();
        Container container = new Container();

        memento.setState("#1. 做饭");
        container.addOrder(memento.saveStateToOrder());
        memento.setState("#2. 炒菜");
        container.addOrder(memento.saveStateToOrder());
        memento.setState("#3. 吃饭");
        container.addOrder(memento.saveStateToOrder());

        System.out.println(memento.getState());
        memento.getStateFromOrder(container.getOrder(0));
        System.out.println("备忘录:" + memento.getState());
        memento.getStateFromOrder(container.getOrder(1));
        System.out.println("备忘录:" + memento.getState());
        memento.getStateFromOrder(container.getOrder(2));
        System.out.println("备忘录:" + memento.getState());

    }
}

2.5 运行结果

#3. 吃饭
备忘录:#1. 做饭
备忘录:#2. 炒菜
备忘录:#3. 吃饭

3. 使用场景

  • 撤销和重做功能 :在文本编辑器中,如Word或记事本,用户可以使用Ctrl+Z组合键来撤销最近的操作,而Ctrl+Y组合键则用于重做。这种场景非常适合使用备忘录模式,因为它允许用户在不破坏封装性的情况下回滚到之前的状态。
  • 游戏存档:在游戏开发中,备忘录模式可以用于保存玩家的游戏进度,使得玩家可以在任何时候从之前的状态继续游戏。这不仅提高了游戏的可玩性,还增强了玩家的游戏体验。
  • 数据库事务管理:在数据库操作中,备忘录模式可以用于事务管理,确保在执行一系列操作之前能够恢复到事务开始前的状态。这对于保证数据的一致性和完整性非常有用。
  • 日志记录和错误恢复:在软件开发中,备忘录模式可以用于日志记录和错误恢复。通过保存程序执行过程中的状态快照,可以在出现问题时快速恢复到之前的状态,从而减少调试时间和成本。
  • 持久化状态:有时需要将对象的状态保存到磁盘或数据库中,以便在以后的时间点恢复。备忘录模式可以方便地将对象的状态序列化并保存,从而实现持久化。
  • 浏览器回退功能:浏览器通常提供回退功能,允许用户通过点击历史记录按钮返回到之前的页面。这种场景也可以使用备忘录模式来实现,通过保存页面加载的历史状态。

需要注意的是,虽然备忘录模式提供了灵活的状态恢复机制,但也存在一些潜在的问题。例如,它可能会导致资源消耗增加,特别是在需要保存大量状态的情况下。因此,在实际应用中需要权衡其利弊,并根据具体需求进行适当的调整和优化

4. 优缺点

  • 备忘录模式的优点
    • 状态保存和恢复功能方便
      可以方便地保存对象的状态,并且在需要的时候准确地恢复对象的状态。这在实现撤销 / 重做功能等场景下非常有用。就像在图形编辑软件中,用户可以利用备忘录模式轻松地撤销之前的绘图操作,恢复到之前的图形状态。
    • 保持封装性
      原发器的状态被保存在备忘录中,备忘录的内部结构对其他对象是隐藏的。这样可以确保原发器状态的完整性和安全性,防止外部对象对其状态进行不适当的访问和修改。例如,在一个复杂的游戏角色状态保存场景中,游戏角色(原发器)的状态细节(如等级、装备等)被安全地封装在备忘录中,只有通过角色本身的恢复方法才能正确地使用这些状态信息。
  • 备忘录模式的缺点
    • 资源消耗
      如果需要频繁地保存对象的状态,可能会消耗大量的内存空间来存储备忘录。例如,在一个实时视频编辑软件中,如果对每一帧画面的状态都使用备忘录模式进行保存,将会占用巨大的内存资源。
    • 复杂的状态管理
      当原发器的状态比较复杂,涉及多个数据成员和复杂的对象关系时,备忘录的管理和状态恢复可能会变得比较复杂。例如,在一个企业资源规划(ERP)系统中,一个业务流程对象(原发器)的状态可能涉及多个子模块的状态信息,使用备忘录模式来保存和恢复状态就需要仔细地处理这些复杂的状态关系。

5. 总结

这里的例子与网上的不一样,这里可以实现多个回退

相关推荐
半夏知半秋43 分钟前
unity打包流程整理-Windows/Mac/Linux平台
windows·笔记·学习·macos·unity·游戏引擎
岳轩子3 小时前
23种设计模式之中介者模式
设计模式·中介者模式
丁劲犇4 小时前
让 Win10 上网本 Debug 模式 QUDPSocket 信号&槽 收发不丢包的方法总结
网络·windows·qt·网络协议·udp·qudpsocket·丢包
Vincent(朱志强)6 小时前
设计模式详解(十):策略模式——Strategy
设计模式·策略模式
WangMing_X7 小时前
C# 23种设计模式(1)单例模式(单件模式)
单例模式·设计模式
wkj0017 小时前
PHP开发设计模式:单例模式
单例模式·设计模式·php
不爱吃米饭_8 小时前
工作中常用的8种设计模式
设计模式
岳轩子8 小时前
23种设计模式之命令模式
设计模式·命令模式