找回密码
 立即注册
首页 业界区 业界 掌握设计模式--备忘录模式

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

麓吆 3 天前
备忘录模式(Memento Pattern)

备忘录模式(Memento Pattern)是一种行为型设计模式,用于在不暴露对象内部实现细节的情况下,捕获对象的内部状态,并在需要时恢复到先前的状态。该模式通常用于需要撤销和恢复操作的场景。
核心思想:在不破坏对象封装的前提下,捕获并保存对象的内部状态,以便在需要时恢复到之前的状态。
主要组成部分


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

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

1.png

Commit(提交)

提交类包含着所提交的所有信息,这里仅仅记录提交时的备注信息。
  1. public class Commit {
  2.     private final String content;
  3.     public Commit(String content) {
  4.         this.content = content;
  5.     }
  6.     public String getContent() {
  7.         return content;
  8.     }
  9. }
复制代码
GitRepository(版本库)
  1. public class GitRepository {
  2.     private String content;
  3.     public GitRepository(String content) {
  4.         this.content = content;
  5.     }
  6.     public String getContent() {
  7.         return content;
  8.     }
  9.     public void setContent(String content) {
  10.         this.content = content;
  11.     }
  12.     // 创建提交(备忘录)
  13.     public Commit saveToCommit() {
  14.         return new Commit(content);
  15.     }
  16.     // 从提交恢复
  17.     public void restoreFromCommit(Commit commit) {
  18.         this.content = commit.getContent();
  19.     }
  20. }
复制代码
VersionControl(版本控制)

为了简化代码,List的序列号为版本号
  1. public class VersionControl {
  2.     private List<Commit> commitHistory = new ArrayList<>();
  3.     private GitRepository repository;
  4.     public VersionControl(GitRepository repository) {
  5.         this.repository = repository;
  6.     }
  7.     // 提交当前状态
  8.     public void commit() {
  9.         commitHistory.add(repository.saveToCommit());
  10.         System.out.println("Committed: " + repository.getContent());
  11.     }
  12.     // 查看历史提交
  13.     public void showHistory() {
  14.         System.out.println("Commit History:");
  15.         for (int i = 0; i < commitHistory.size(); i++) {
  16.             System.out.println("\tCommit " + (i + 1) + ": " + commitHistory.get(i).getContent());
  17.         }
  18.     }
  19.     // 恢复到某个历史提交
  20.     public void restore(int commitIndex) {
  21.         if (commitIndex >= 0 && commitIndex < commitHistory.size()) {
  22.             repository.restoreFromCommit(commitHistory.get(commitIndex));
  23.             System.out.println("Restored to: " + repository.getContent());
  24.         } else {
  25.             System.out.println("Invalid commit index!");
  26.         }
  27.     }
  28. }
复制代码
测试代码
  1. public class GitDemo {
  2.     public static void main(String[] args) {
  3.         // 创建一个GitRepository对象,模拟一个文件的内容
  4.         GitRepository repository = new GitRepository("初始化仓库");
  5.         // 创建版本控制系统
  6.         VersionControl versionControl = new VersionControl(repository);
  7.         // 提交当前状态
  8.         versionControl.commit();
  9.         // 修改文件内容并提交
  10.         repository.setContent("新增功能");
  11.         versionControl.commit();
  12.         // 修改文件内容并提交
  13.         repository.setContent("修复bugs");
  14.         versionControl.commit();
  15.         // 查看历史提交
  16.         versionControl.showHistory();
  17.         // 恢复到第二个提交
  18.         versionControl.restore(1);
  19.         // 修改并再次提交
  20.         repository.setContent("功能调整");
  21.         versionControl.commit();
  22.         // 查看历史提交
  23.         versionControl.showHistory();
  24.     }
  25. }
复制代码
执行结果
  1. Committed: 初始化仓库
  2. Committed: 新增功能
  3. Committed: 修复bugs
  4. Commit History:
  5. Commit 1: 初始化仓库
  6. Commit 2: 新增功能
  7. Commit 3: 修复bugs
  8. Restored to: 新增功能
  9. Committed: 功能调整
  10. Commit History:
  11. Commit 1: 初始化仓库
  12. Commit 2: 新增功能
  13. Commit 3: 修复bugs
  14. Commit 4: 功能调整
复制代码
代码简析

GitRepository 类模拟一个代码文件的内容,并具有修改内容和创建备忘录(提交)的方法
Commit 类作为备忘录,保存文件的某个版本(即内容)
VersionControl 类充当版本控制系统,负责管理所有提交(备忘录),可以查看提交历史、创建新提交以及恢复历史版本
命令模式和备忘录模式对比

备忘录模式重点在于保存和恢复状态,用于保存对象的历史状态并在需要时恢复,不改变对象的外部接口。
命令模式重点在于请求的封装和解耦,用于将请求的发送者和接收者解耦,使得请求者不必知道如何执行操作,增加了操作的灵活性。
举例

备忘录模式
假设你有一个文本编辑器,用户输入了一段文本。你可以使用备忘录模式保存文本的状态,当用户点击撤销按钮时,编辑器恢复到之前保存的文本状态。
命令模式
假设你在一个远程控制器中,按下按钮后它发送一个命令来打开电视。电视接收命令并执行打开操作。通过命令模式,可以将按钮点击与电视操作解耦,且可以轻松实现撤销和重做功能,或将操作排队执行。
总结

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

  • 状态管理:备忘录模式允许对象在某一时刻保存状态,并且可以在以后恢复到这个状态。这对于需要撤销或恢复的应用场景非常有用,比如文本编辑器、游戏进度保存等。
  • 内部封装:备忘录对象封装了原对象的状态,但不允许外部直接修改这些状态,保护了原对象的内部数据。通常,备忘录对象是“只读”的,只有原对象可以恢复或修改其内容。
2.gif

需要查看往期设计模式文章的,可以在个人主页中或者文章开头的集合中查看,可关注我,持续更新中。。。
超实用的SpringAOP实战之日志记录
2023年下半年软考考试重磅消息
通过软考后却领取不到实体证书?
计算机算法设计与分析(第5版)
Java全栈学习路线、学习资源和面试题一条龙
软考证书=职称证书?
软考中级--软件设计师毫无保留的备考分享

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册