设计模式-备忘录模式

设计模式专栏



模式介绍

备忘录模式(Memento Pattern)是一种对象行为型模式,又被称为快照模式或Token模式。该模式的主要目标是,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。

备忘录模式适用于需要记录和恢复对象内部状态的场景。例如,在实现撤销和重做功能时,可以使用备忘录模式来保存和恢复对象的状态。

备忘录模式主要涉及三个角色:发起人(Originator)备忘录(Memento)管理者(Caretaker)

发起人(Originator):记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。

备忘录(Memento):负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。

管理者(Caretaker):对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。

备忘录模式的优点主要包括:

  1. 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
  2. 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
  3. 简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

然而,备忘录模式也有其缺点:资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

模式特点

备忘录模式是一种对象行为型模式,其主要特点如下:

  1. 捕获并保存状态:备忘录模式允许在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这意味着对象的状态可以在任何时候被保存,以便以后需要时能恢复到先前的状态。
  2. 简化发起人类:备忘录模式简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。
  3. 封装内部状态:除了创建它的发起人之外,其他对象都不能够访问这些状态信息。备忘录模式实现了内部状态的封装,对其他对象屏蔽了发起人对象的内部信息。
  4. 资源消耗:备忘录模式的主要缺点是资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

总的来说,备忘录模式提供了一种可以恢复状态的机制,简化了对象的行为,同时实现了内部状态的封装。然而,它也有一定的资源消耗。在实际应用中,需要根据具体需求和资源情况来决定是否使用备忘录模式。

应用场景

备忘录模式的应用场景主要包括:

  1. 撤销操作:在需要保存和恢复数据的相关业务场景中,备忘录模式非常适用。例如,在Word中编写文档时,如果想要撤销之前的输入或删除操作,可以使用Ctrl+Z执行"撤销"操作,这就是备忘录模式的一个应用。
  2. 状态恢复:当需要在"后悔"的时候将对象恢复到之前的状态时,也可以使用备忘录模式。例如,在游戏中的存档功能,就是典型的备忘录模式应用。

在这些场景中,备忘录模式提供了一种可以恢复状态的机制,通过封装存档信息,为用户提供了一种可以恢复到之前状态的可能性。

备忘录模式和迭代器模式的区别

备忘录模式和迭代器模式是两种不同的设计模式,它们在目的、使用场景和实现方式上有显著的区别。

  1. 目的与功能:备忘录模式的核心目标是保存和恢复对象的状态。它主要用于在不破坏封装性的情况下,捕获一个对象的内部状态,并在对象之外保存这个状态,以便之后可以恢复对象到先前的状态。而迭代器模式的主要目的是遍历集合对象,它允许在不影响对象内部结构的情况下,顺序访问一个聚合对象的各个元素,而无需暴露其内部的表示。
  2. 使用场景:备忘录模式适用于需要撤销和重做操作,或者需要保存和恢复对象状态的场景。例如,游戏中的进度保存和载入,或者编辑器中的撤销/重做操作等。而迭代器模式则适用于需要遍历集合对象的情况,例如在处理数组、列表、树等数据结构时,可以使用迭代器模式来简化遍历操作。
  3. 实现方式:备忘录模式通常包含发起人、备忘录和管理者三个角色。发起人负责创建备忘录并恢复状态,备忘录负责存储状态信息,管理者则负责保存和提供备忘录的访问。而迭代器模式通常包含聚合和迭代器两个角色。聚合定义了存储、添加、删除元素以及创建迭代器的方法,迭代器则定义了访问和遍历元素的方法。

总结来说,备忘录模式和迭代器模式在目的、使用场景和实现方式上都有所不同。备忘录模式关注于保存和恢复对象的状态,而迭代器模式则关注于遍历集合对象。在实际应用中,需要根据具体需求来选择合适的设计模式。

代码示例

Java实现备忘录模式

备忘录模式在Java中的实现主要涉及三个角色:发起人(Originator)、备忘录(Memento)和管理者(Caretaker)。以下是一个简单的Java实现示例:

java 复制代码
// 发起人(Originator)
public class Originator {
    private String state;

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

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

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

    public String getState() {
        return state;
    }
}

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

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

    public String getState() {
        return state;
    }
}

// 管理者(Caretaker)
public class Caretaker {
    private Memento memento;

    public Caretaker(Memento memento) {
        this.memento = memento;
    }

    public Memento getMemento() {
        return memento;
    }
}

使用示例:

java 复制代码
public class Main {
    public static void main(String[] args) {
        Originator originator = new Originator("Initial State");
        Memento memento = originator.createMemento(); // 创建备忘录
        System.out.println("Current state: " + originator.getState()); // 修改状态,输出 "Current state: New State" 或其他用户输入的字符串。这可以是用户的操作、业务逻辑的执行等。
        Caretaker caretaker = new Caretaker(memento); // 将备忘录交给管理者(Caretaker)保管。这可以是一个文件、数据库、内存等存储介质。
        originator.restoreFromMemento(caretaker.getMemento()); // 从备忘录恢复状态。这可以是用户请求撤销操作,或者程序需要回滚到之前的状态。输出 "Restored state: Initial State"。
    }
}

这是一个非常简化的示例,用于说明备忘录模式的基本概念。在实际应用中,发起人、备忘录和管理者的定义和实现可能更加复杂,涉及更多的属性和方法。

Python实现备忘录模式

以下是一个Python实现备忘录模式的示例:

python 复制代码
class Originator:
    def __init__(self, state):
        self.state = state

    def create_memento(self):
        return Memento(self.state)

    def restore_from_memento(self, memento):
        self.state = memento.get_state()

class Memento:
    def __init__(self, state):
        self.state = state

    def get_state(self):
        return self.state

class Caretaker:
    def __init__(self):
        self.memento = None

    def set_memento(self, memento):
        self.memento = memento

    def get_memento(self):
        return self.memento

使用示例:

python 复制代码
originator = Originator("Initial State")
memento = originator.create_memento()  # 创建备忘录
print("Current state:", originator.state)  # 修改状态,例如originator.state = "New State" 或其他用户输入的字符串。这可以是用户的操作、业务逻辑的执行等。
caretaker = Caretaker()
caretaker.set_memento(memento)  # 将备忘录交给管理者(Caretaker)保管。这可以是一个文件、数据库、内存等存储介质。
originator.restore_from_memento(caretaker.get_memento())  # 从备忘录恢复状态。这可以是用户请求撤销操作,或者程序需要回滚到之前的状态。输出 "Restored state: Initial State"。

这个示例展示了备忘录模式的基本概念,但实际应用中可能需要更复杂的实现和更多的细节处理。

备忘录模式在spring中的应用

备忘录模式在Spring框架中有很多应用场景,下面是一些常见的示例:

  1. 撤销操作:在Spring MVC框架中,我们可以使用备忘录模式实现撤销功能。比如在表单提交操作后,我们保存一份表单数据的备忘录,当用户想要撤销操作时,我们恢复这份备忘录中的数据。
  2. 状态管理:在Spring框架中,我们可以使用备忘录模式来管理Bean的状态。比如在一个复杂的业务逻辑中,我们可以将Bean的状态保存为备忘录,然后在需要的时候恢复这个状态。
  3. 事务管理:在Spring框架中,事务管理是一个常见的使用场景。我们可以将事务状态保存为备忘录,当出现异常时,我们可以回滚到之前的状态。
  4. 安全控制:在Spring框架中,我们可以使用备忘录模式来保存用户的登录状态。当用户登录后,我们将用户的登录状态保存为备忘录,这样在用户后续的操作中,我们就可以通过恢复备忘录中的状态来进行权限控制。

在实际应用中,备忘录模式可以与Spring框架中的其他模式(如拦截器、过滤器等)结合使用,实现更复杂的功能。

设计模式-责任链模式
设计模式-状态模式
设计模式-代理模式

相关推荐
哎呦没6 分钟前
SpringBoot框架下的资产管理自动化
java·spring boot·后端
m0_571957582 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟6 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity7 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天7 小时前
java的threadlocal为何内存泄漏
java
caridle7 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^7 小时前
数据库连接池的创建
java·开发语言·数据库