【设计模式系列】备忘录模式(十九)

目录

一、什么是备忘录模式

二、备忘录模式的角色

三、备忘录模式的典型应用场景

四、备忘录模式在Calendar中的应用


一、什么是备忘录模式

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

二、备忘录模式的角色

  1. 发起人(Originator):负责创建一个备忘录对象,用于保存当前时刻的内部状态,并可以使用备忘录恢复其内部状态 。发起人可以根据需求决定备忘录存储哪些内部状态 。

  2. 备忘录(Memento):负责存储发起人对象的内部状态,并封装这些状态,防止除了发起人之外的其他对象访问备忘录 。备忘录通常包含两个接口,一个窄接口供管理者使用,一个宽接口供发起人使用 。

  3. 管理者(Caretaker):负责保存好备忘录对象,但不能对备忘录的内容进行操作或检查。管理者可以决定保存哪些备忘录以及保存多久 。

三、备忘录模式的典型应用场景

  • 版本管理场景:备忘录模式可以用来保存每个版本的状态。当需要回滚到之前的版本时,可以通过备忘录模式恢复到历史状态 。

四、备忘录模式在Calendar**中的应用**

备忘录模式在Calendar应用中可以用于实现日期的撤销(Undo)和重做(Redo)功能。在这种应用中,用户可能需要恢复到某个特定的日期。以下是备忘录模式在Calendar中的具体应用:

首先先创建一个备忘录,用来存储一个日历中的日期、所要记录的事项。

java 复制代码
public class CalendarEventMemento {
    private final String title;
    private final String date;
    private final String description;

    public CalendarEventMemento(String title, String date, String description) {
        this.title = title;
        this.date = date;
        this.description = description;
    }

    // 只提供 getter 方法以保证备忘录的不可变性
    public String getTitle() {
        return title;
    }

    public String getDate() {
        return date;
    }

    public String getDescription() {
        return description;
    }
} 

然后我们创建一个发起人,可以创建日历来保存状态,也可以恢复某一状态

java 复制代码
public class CalendarEvent {
    private String title;
    private String date;
    private String description;

    public CalendarEvent(String title, String date, String description) {
        this.title = title;
        this.date = date;
        this.description = description;
    }

    // 创建备忘录
    public CalendarEventMemento save() {
        return new CalendarEventMemento(title, date, description);
    }

    // 从备忘录恢复
    public void restore(CalendarEventMemento memento) {
        this.title = memento.getTitle();
        this.date = memento.getDate();
        this.description = memento.getDescription();
    }

    // Getters and Setters
    public void setTitle(String title) {
        this.title = title;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "事件: " + title + ", 日期: " + date + ", 描述: " + description;
    }
} 

最后,我们创建一个管理者,用来管理历史日历状态

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

public class CalendarCaretaker {
    private List<CalendarEventMemento> mementoList = new ArrayList<>();

    public void addMemento(CalendarEventMemento memento) {
        mementoList.add(memento);
    }

    public CalendarEventMemento getMemento(int index) {
        return mementoList.get(index);
    }
} 

其中,客户端代码示例如下:

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 创建日历事件管理者
        CalendarCaretaker caretaker = new CalendarCaretaker();
        
        // 创建原始日历事件
        CalendarEvent event = new CalendarEvent("团队会议", "2024-03-20", "讨论项目进度");
        System.out.println("原始事件: " + event);

        // 保存当前状态
        caretaker.addMemento(event.save());

        // 修改事件
        event.setTitle("紧急会议");
        event.setDescription("讨论重要客户需求");
        System.out.println("修改后的事件: " + event);

        // 再次保存状态
        caretaker.addMemento(event.save());

        // 恢复到第一个状态
        event.restore(caretaker.getMemento(0));
        System.out.println("恢复到初始状态: " + event);

        // 恢复到第二个状态
        event.restore(caretaker.getMemento(1));
        System.out.println("恢复到第二个状态: " + event);
    }
} 
相关推荐
古法老登瞎折腾2 小时前
大数据智能运维实战(十一):运维 MCP 的工程化——权限、限流、审计与错误处理
java·大数据·运维·spring ai·mcp
智能运维指南3 小时前
研制过程“两张皮“怎么破:研制一体化支撑平台的定位、能力边界与落地前提
java·前端·人工智能·嘉为蓝鲸
yz_aiks4 小时前
Spring AI 2.1 ChatMemory 已过时用什么替代:迁移到 Session Memory 实战(JDBC 存储与会话压缩)
java·spring boot·大模型·ai agent·spring ai
金銀銅鐵4 小时前
[Java] 用 GUI 展示 EnumMap 增删键值对时的内部变化
java·后端·ai编程
学长毕设4 小时前
基于SpringBoot的上门洗车服务系统设计与实现
java·spring boot·后端
jason成都4 小时前
RTKLIB-Java 多基线联合RTK:FIX率从0%到91.5%的三层根因修复
java·gnss·rtklib·rtklib_java
鱼宵5 小时前
Stream 终端操作一次讲透:collect、count、reduce 怎么选
java·stream·终端操作
白山编程大哥5 小时前
Java 后端如何优雅地把 List 集合返回给前端
java·前端·list
Linux运维技术栈5 小时前
CVE-2026-91403 高危漏洞修复:Rocky Linux 9 多版本 JDK 环境清理实操
java·linux·运维
On The Road :5 小时前
Java 多线程详解:从入门到线程安全
java·python·安全