掌握设计模式--备忘录模式

备忘录模式(Memento Pattern)

备忘录模式(Memento Pattern)是一种行为型设计模式,用于在不暴露对象内部实现细节的情况下,捕获对象的内部状态,并在需要时恢复到先前的状态。该模式通常用于需要撤销和恢复操作的场景。

核心思想:在不破坏对象封装的前提下,捕获并保存对象的内部状态,以便在需要时恢复到之前的状态。

主要组成部分

  1. Originator(发起人):负责创建和保存备忘录对象。它可以恢复到之前的状态。
  2. Memento(备忘录):存储发起人对象的内部状态,允许发起人恢复到此状态。它通常是一个简单的封装类,只保存状态信息。
  3. Caretaker(看护者):负责管理备忘录对象的生命周期,保存备忘录,但不会修改备忘录的内容。看护者可以随时请求发起人对象创建备忘录,并在需要时提供备忘录。

案例实现

Git 是一个典型的版本控制工具,适用备忘录模式来实现简化的版本控制。备忘录模式通过保存每个文件或项目的状态快照,允许我们随时恢复到先前的版本。虽然 Git 的实现更加复杂,并且具有更多的功能(如分支管理、合并等),我们可以通过备忘录模式来实现一个简单的版本控制系统。

下面是一个使用备忘录模式模拟简单版本控制的实现:

案例类图

Commit(提交)

提交类包含着所提交的所有信息,这里仅仅记录提交时的备注信息。

public class Commit {
 private final String content;
 public Commit(String content) {
 this.content = content;
 }
 public String getContent() {
 return content;
 }
}

GitRepository(版本库)

public class GitRepository {
 private String content;
 public GitRepository(String content) {
 this.content = content;
 }
 public String getContent() {
 return content;
 }
 public void setContent(String content) {
 this.content = content;
 }
 // 创建提交(备忘录)
 public Commit saveToCommit() {
 return new Commit(content);
 }
 // 从提交恢复
 public void restoreFromCommit(Commit commit) {
 this.content = commit.getContent();
 }
}

VersionControl(版本控制)

为了简化代码,List的序列号为版本号

public class VersionControl {
 private List<Commit> commitHistory = new ArrayList<>();
 private GitRepository repository;
 public VersionControl(GitRepository repository) {
 this.repository = repository;
 }
 // 提交当前状态
 public void commit() {
 commitHistory.add(repository.saveToCommit());
 System.out.println("Committed: " + repository.getContent());
 }
 // 查看历史提交
 public void showHistory() {
 System.out.println("Commit History:");
 for (int i = 0; i < commitHistory.size(); i++) {
 System.out.println("\tCommit " + (i + 1) + ": " + commitHistory.get(i).getContent());
 }
 }
 // 恢复到某个历史提交
 public void restore(int commitIndex) {
 if (commitIndex >= 0 && commitIndex < commitHistory.size()) {
 repository.restoreFromCommit(commitHistory.get(commitIndex));
 System.out.println("Restored to: " + repository.getContent());
 } else {
 System.out.println("Invalid commit index!");
 }
 }
}

测试代码

public class GitDemo {
 public static void main(String[] args) {
 // 创建一个GitRepository对象,模拟一个文件的内容
 GitRepository repository = new GitRepository("初始化仓库");
 // 创建版本控制系统
 VersionControl versionControl = new VersionControl(repository);
 // 提交当前状态
 versionControl.commit();
 // 修改文件内容并提交
 repository.setContent("新增功能");
 versionControl.commit();
 // 修改文件内容并提交
 repository.setContent("修复bugs");
 versionControl.commit();
 // 查看历史提交
 versionControl.showHistory();
 // 恢复到第二个提交
 versionControl.restore(1);
 // 修改并再次提交
 repository.setContent("功能调整");
 versionControl.commit();
 // 查看历史提交
 versionControl.showHistory();
 }
}

执行结果

Committed: 初始化仓库
Committed: 新增功能
Committed: 修复bugs
Commit History:
Commit 1: 初始化仓库
 Commit 2: 新增功能
 Commit 3: 修复bugs
Restored to: 新增功能
Committed: 功能调整
Commit History:
 Commit 1: 初始化仓库
 Commit 2: 新增功能
 Commit 3: 修复bugs
 Commit 4: 功能调整

代码简析

GitRepository 类模拟一个代码文件的内容,并具有修改内容和创建备忘录(提交)的方法

Commit 类作为备忘录,保存文件的某个版本(即内容)

VersionControl 类充当版本控制系统,负责管理所有提交(备忘录),可以查看提交历史、创建新提交以及恢复历史版本

命令模式和备忘录模式对比

备忘录模式重点在于保存和恢复状态,用于保存对象的历史状态并在需要时恢复,不改变对象的外部接口。

命令模式重点在于请求的封装和解耦,用于将请求的发送者和接收者解耦,使得请求者不必知道如何执行操作,增加了操作的灵活性。

举例

备忘录模式
假设你有一个文本编辑器,用户输入了一段文本。你可以使用备忘录模式保存文本的状态,当用户点击撤销按钮时,编辑器恢复到之前保存的文本状态。

命令模式
假设你在一个远程控制器中,按下按钮后它发送一个命令来打开电视。电视接收命令并执行打开操作。通过命令模式,可以将按钮点击与电视操作解耦,且可以轻松实现撤销和重做功能,或将操作排队执行。

总结

备忘录模式的核心关注点是保存对象的内部状态,并在需要时恢复到先前的状态,而不暴露对象的实现细节。这通常用于实现撤销、回退功能。

  • 状态管理:备忘录模式允许对象在某一时刻保存状态,并且可以在以后恢复到这个状态。这对于需要撤销或恢复的应用场景非常有用,比如文本编辑器、游戏进度保存等。

  • 内部封装:备忘录对象封装了原对象的状态,但不允许外部直接修改这些状态,保护了原对象的内部数据。通常,备忘录对象是“只读”的,只有原对象可以恢复或修改其内容。

需要查看往期设计模式文章的,可以在个人主页中或者文章开头的集合中查看,可关注我,持续更新中。。。


超实用的SpringAOP实战之日志记录

2023年下半年软考考试重磅消息

通过软考后却领取不到实体证书?

计算机算法设计与分析(第5版)

Java全栈学习路线、学习资源和面试题一条龙

软考证书=职称证书?

软考中级--软件设计师毫无保留的备考分享

作者:渊渟岳原文地址:https://www.cnblogs.com/dennyLee2025/p/18793702

%s 个评论

要回复文章请先登录注册