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

备忘录模式(Memento Pattern)

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

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

主要组成部分

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

案例实现

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

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

案例类图

Commit(提交)

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

java 复制代码
public class Commit {
    private final String content;

    public Commit(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }
}

GitRepository(版本库)

java 复制代码
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的序列号为版本号

java 复制代码
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!");
        }
    }
}

测试代码

java 复制代码
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全栈学习路线、学习资源和面试题一条龙

软考证书=职称证书?

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

相关推荐
十五年专注C++开发8 分钟前
设计模式之适配器模式(二):STL适配器
c++·设计模式·stl·适配器模式·包装器
渊渟岳1 小时前
掌握设计模式--中介者模式
设计模式
云徒川1 小时前
【设计模式】单例模式
设计模式
木子庆五7 小时前
Android设计模式之模板方法模式
android·设计模式·模板方法模式
Antonio9159 小时前
【设计模式】状态模式
设计模式
木子庆五12 小时前
Android设计模式之工厂方法模式
android·设计模式·工厂方法模式
Absinthe_苦艾酒1 天前
设计模式之适配器模式
设计模式·适配器模式
Zfox_1 天前
【Linux】高性能网络模式:Reactor 反应堆模式
linux·服务器·c++·设计模式·性能优化·reactor
木子庆五1 天前
Android 设计模式之适配器模式
android·设计模式·适配器模式
找了一圈尾巴2 天前
设计模式(创建型)-建造者模式
设计模式·建造者模式