设计模式备忘录+命令模式实现Word撤销恢复操作

news2024/11/26 10:29:43

文章目录

  • 前言
  • 思路
  • 代码实现
  • uml类图
  • 总结

前言

最近学习设计模式行为型的模式,学到了备忘录模式提到这个模式可以记录一个对象的状态属性值,用于下次复用,于是便想到了我们在Windows系统上使用的撤销操作,于是便想着使用这个模式进行一次模仿复现

思路

以下是按照备忘录和命令模式结合的思路描述:

  1. 首先,我们有一个文档类 Document,其中包含一个文本属性。文档类提供了设置和获取文本的方法。

  2. 我们引入备忘录类 Memento,用于保存文档对象的状态。

  3. 文档类还实现了创建备忘录和恢复备忘录的方法。创建备忘录时,文档对象会将当前的文本状态传递给备忘录对象进行保存。恢复备忘录时,文档对象会从备忘录对象中获取之前保存的文本状态并恢复。

  4. 为了实现可逆操作和撤销功能,我们引入了命令接口 Command,该接口定义了执行方法 execute() 和撤销方法 undo()

  5. 具体命令类 InsertTextCommand 是一个插入文本操作的具体实现。在执行命令时,该命令对象会调用文档对象的插入文本方法,并将执行前的文本状态保存到备忘录对象中。在撤销命令时,该命令对象会使用备忘录对象恢复文档的文本状态。

  6. 历史记录类 History 充当调用者的角色,用于记录执行的命令。它内部使用一个列表来保存命令对象。每次执行命令时,该命令对象被添加到列表中保存;每次撤销命令时,列表的最后一个命令对象被取出并执行其撤销操作。

  7. 在主程序中,我们实例化了文档对象、备忘录对象和历史记录对象。

  8. 执行插入文本命令1,创建插入文本命令对象并将其添加到历史记录对象的列表中。该命令对象会执行插入文本操作,并将执行前的文本状态保存到备忘录对象中。

  9. 执行插入文本命令2,同样创建插入文本命令对象并将其添加到历史记录对象的列表中。该命令对象也会执行插入文本操作,并将执行前的文本状态保存到备忘录对象中。

  10. 执行撤销命令,历史记录对象的列表中取出最后一个命令对象(即插入文本命令2),并执行其撤销操作。命令对象会从备忘录对象中获取之前保存的文本状态,恢复文档的内容。

  11. 输出文档的内容,即输出 “Hello”。

  12. 再次执行撤销命令,历史记录对象的列表中取出插入文本命令1,并执行其撤销操作。文档的内容变为空字符串。

  13. 输出文档的内容,即输出空字符串。

  14. 尝试再次执行撤销命令,由于历史记录中已没有可撤销的命令,不会执行任何操作。

  15. 最后,输出文档的内容,依然输出空字符串。

代码实现

实现类似于 Word 文档中的撤销和恢复操作,可以采用备忘录模式配合命令模式的方式。

  1. 备忘录类(Memento):备忘录类负责存储文档的状态。它可以保存文档的内容、样式、光标位置等信息。
class Memento {
    private String content;
    private String style;
    private int cursorPosition;

    // 构造函数和访问方法
}
  1. 命令接口(Command):命令接口定义执行和撤销操作的方法。
interface Command {
    void execute();
    void undo();
}
  1. 具体命令类(具体的操作):实现命令接口,执行和撤销文档的具体操作。例如,插入文本、修改样式、移动光标等。
class InsertTextCommand implements Command {
    private Document document;
    private Memento prevState;
    private String newText;

    public InsertTextCommand(Document document, String newText) {
        this.document = document;
        this.newText = newText;
    }

    public void execute() {
        prevState = document.createMemento();
        document.setText(newText);
    }

    public void undo() {
        document.restore(prevState);
    }
}
  1. 文档类(Originator):文档类维护文档的状态,并提供创建备忘录、恢复状态和执行操作的方法。
class Document {
    private String text;

    public void setText(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

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

    public void restore(Memento memento) {
        text = memento.getState();
    }
}
  1. 历史记录类(Caretaker):历史记录类负责存储备忘录对象,并管理执行和撤销操作的命令。
class History {
    private Stack<Command> commandStack;

    public History() {
        commandStack = new Stack<>();
    }

    public void executeCommand(Command command) {
        command.execute();
        commandStack.push(command);
    }

    public void undo() {
        if (!commandStack.isEmpty()) {
            Command command = commandStack.pop();
            command.undo();
        }
    }
}

使用以上设计的示例代码如下:

    public static void main(String[] args) {
        // 创建文档对象和历史记录对象
        Document document = new Document();
        History history = new History();

        // 执行命令:插入文本
        Command insertCommand1 = new InsertTextCommand(document, "Hello");
        history.executeCommand(insertCommand1);

        // 执行命令:插入文本
        Command insertCommand2 = new InsertTextCommand(document, " World!");
        history.executeCommand(insertCommand2);
        

        // 输出文档内容
        System.out.println(document.getText());  // 输出:World!

        // 执行命令:撤销上一个命令
        history.undo();

        // 输出文档内容
        System.out.println(document.getText());  // 输出:hello

        // 执行命令:撤销上一个命令(没有可撤销的命令)
        history.undo();  // 不执行任何操作

        // 输出文档内容
        System.out.println(document.getText());  // 输出:""
    }

在这里插入图片描述

通过使用备忘录模式和命令模式,我们可以记录文档状态的变化,并在需要时进行撤销和恢复操作。每次执行操作时,都会创建对应的命令对象,并将其添加到历史记录中,以支持撤销和重做操作。

uml类图

在这里插入图片描述

总结

这个功能的实现使用了备忘录模式和命令模式两种设计模式。

备忘录模式用于保存文档对象的状态,并提供了恢复状态的功能。它将文档对象的状态封装在备忘录对象中,以便在需要时可以对其进行保存并恢复。这样,可以在不破坏文档对象封装性的情况下,实现文档对象的状态管理和回滚功能。

命令模式用于执行和撤销操作。通过将每个操作封装在一个命令对象中,并提供统一的执行和撤销方法,可以实现对操作的统一管理和控制。这样,可以方便地扩展和组合不同的操作,同时也解耦了调用者和接收者。

使用设计模式的好处包括:

  1. 提高代码的可维护性和可扩展性:设计模式使代码结构更清晰、更易于理解和维护。模式中定义了明确的角色和关系,使代码具有良好的组织结构和可扩展性。

  2. 复用性增加:设计模式通过提供通用的解决方案,使得代码可以在不同场景下被重复使用。这避免了重复编写相似的代码,提高了开发效率。

  3. 降低耦合度:设计模式通过明确角色和关系,将系统中各组件之间的依赖关系降到最低。这样,当需求变化或者需要修改某一个组件时,对其他组件的影响最小,易于维护和扩展。

  4. 提高代码的可测试性:设计模式将逻辑分离开来,使得每个模块可以独立地进行测试,便于编写单元测试和集成测试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/938821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【注册岩土】Python土力学与基础工程计算.PDF-土中的应力

Python 求解代码如下&#xff1a; 1&#xff0e;&#xff03;计算竖向有效自重应力2.h12#m3.h21.5#m4.h31#m5.gamma1 19# kN/m^36.gamma218# kN/m^37.gamma317# kN/m^38.sigma_c gammal * h1 gamma2*h2 gamma3 *h39&#xff0e;print&#xff08;&#xff02;竖向有效自重应力…

STL-空间配置器的了解

前言 空间配置器&#xff0c;顾名思义就是为了各个容器高效的管理空间&#xff08;空间的申请与回收&#xff09;的&#xff0c;在默默的工作的。虽然在常规上使用STL时&#xff0c;可能用不上它&#xff0c;但是站在学习研究的角度&#xff0c;学习它的实现原理对我们有很大的…

Python+Yolov8手势特征识别检测

程序示例精选 PythonYolov8手势特征识别检测 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<PythonYolov8手势特征识别检测>>编写代码&#xff0c;代码整洁&#xff0c;规则&am…

Matlab论文插图绘制模板第109期—特征渲染的标签气泡散点图

在之前的文章中&#xff0c;分享了Matlab标签散点图的绘制模板&#xff1a; 特征渲染的标签散点图&#xff1a; 进一步&#xff0c;再来分享一下特征渲染的标签气泡散点图的绘制模板&#xff0c;从而可以再添加一个维度的信息。 先来看一下成品效果&#xff1a; 特别提示&…

python之socket编程

本章内容 1、socket 2、IO多路复用 3、socketserver Socket socket起源于Unix&#xff0c;而Unix/Linux基本哲学之一就是“一切皆文件”&#xff0c;对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现&#xff0c;socket即是一种特殊的文件&#xff0…

简单工厂模式概述和使用

目录 一、简单工厂模式简介1. 定义2. 使用动机 二、简单工厂模式结构1.模式结构2. 时序图 三、简单工厂的使用实例四、简单工厂模式优缺点五、简单工厂模式在Java中的应用 一、简单工厂模式简介 原文链接 1. 定义 简单工厂模式(Simple Factory Pattern)&#xff1a;又称为静…

Remmina在ubuntu22.04中无法连接Windows

Remmina在ubuntu22.04中无法连接Windows 问题 提示为&#xff1a; 无法通过TLS到RDP服务器… 分析 原因是Remmina需要使用openssl通过RDP加密与Windows计算机连接&#xff0c;而ubuntu22.04系统中OpenSSL版本为3.0&#xff0c;Openssl3 将 tls<1.2 和 sha1 的默认安全级别…

checkstyle检查Java编码样式:源文件和文本文件末尾要有一个空行

背后的原理&#xff1a; 源文件和文本文件末尾应该有一个行分隔符&#xff0c;以便于他人在后面增加新的内容&#xff0c;而“diff”命令不会将前面的行作为改动过来显示。 https://checkstyle.sourceforge.io/checks/misc/newlineatendoffile.html#NewlineAtEndOfFile 例如&a…

外部链接和VUE项目互相跳转实现退出登录

一、补坑总结提前说明 我的项目有一个前台MVC项目门户站点(用户登录信息存储在cookie)&#xff0c;和后台vue项目&#xff08;用户登录信息存储在localstorage&#xff09;站点&#xff0c;2个站点分属不同的端口&#xff0c;那就是跨域了。之前我已经实现过了某个站点登录后&a…

Linux 桌面上的 Firefox 面临着大问题

导读毫无疑问&#xff0c;无论是在桌面、笔记本电脑还是移动设备上&#xff0c;浏览器都是任何操作系统中最重要的应用之一。 如果没有一个功能强大、快速且稳定的浏览器&#xff0c;操作系统的实用性将大幅度降低&#xff0c;以至于我相当确定&#xff0c;如果一个操作系统没有…

C语言二——依次将10个数输入,要求将其中最大的数输出

这是一个简单的C语言程序&#xff0c;它会接受用户输入的10个整数&#xff0c;然后找出最大值并输出。 程序的执行步骤如下&#xff1a; 声明一个数组 n&#xff0c;用于存储用户输入的10个整数&#xff0c;声明一个变量 i 和 t。提示用户输入10个数。使用 for 循环&#xff…

Face2Face: Real-time Face Capture and Reenactment of RGB Videos (CVPR 2016) 译文

建议的在线再现设置:单目目标视频序列(例如&#xff0c;来自Youtube)基于源演员的表达进行再现&#xff0c;源演员使用商品网络摄像头进行现场录制。 摘要 我们提出了一种用于单目目标视频序列(例如Youtube视频)的实时面部再现的新方法。源序列也是单目视频流&#xff0c;用商…

小红书口碑营销技巧有哪些,打造独特品牌内容

作为一款社交电商平台&#xff0c;从目前来看&#xff0c;其实小红书也算是比较不错的口碑营销传播平台了。今天就来带大家一起分享下&#xff0c;小红书口碑营销技巧有哪些&#xff0c;打造独特品牌内容&#xff01; ​ 一、小红书口碑营销怎么做 1. 了解目标用户 首先需要明…

不到3个月,快速上线联创三金MES系统,数字化生产管理初见成效

PART 01 MES系统上线 8月25日&#xff0c;惠州联创三金科技有限公司&#xff08;下文简称联创三金&#xff09;顺利举行了MES系统上线仪式&#xff0c;这标志着联创三金正式运行全新的数字化生产管理系统&#xff0c;迈向了生产管理全面透明化的新阶段。联创集团IT总监邓燕琼…

【Vue3】Pinia状态管理

Pinia pinia与Vuex的对比pinia的介绍pinia与Vuex区别&#xff1a;pinia的使用使用准备步骤一&#xff1a;新建文件导入pinia使用准备步骤二&#xff1a;挂载pinia 创建pinia的Store新建页面。创建对应的Store页面使用pinia的store Pinia核心概念State操作State一重置state改变s…

SciencePub学术 | 计算机智能类重点SCIEEI征稿中

SciencePub学术 刊源推荐: 计算机智能类重点SCIE&EI征稿中&#xff01;信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 计算机智能类重点SCIE&EI 【期刊简介】IF&#xff1a;1.0-1.5&#xff0c;JCR4区&#xff0c;中科院4区&#xff1b; 【检…

Google Play商店优化排名因素之应用标题

对于用户数量和应用数量而言&#xff0c;Google Play 商店是最大的应用商店。市场巨大&#xff0c;同时机遇也巨大。然而由于有近 250 万个应用程序&#xff0c;竞争也同样激烈。 1、应用程序标题是所有排名因素中最强的。 与Apple的30个字符限制相反&#xff0c;Google Play商…

初识Java 1-1 面向对象的语言

目录 引用的作用 数据的储存 常见的数据储存方式 特殊储存的基本类型 数组 销毁对象 基本类型的作用域 对象的作用域 创建新类型 - class关键字 方法、参数和返回值 参数列表 编写程序 名称可见性 使用组件 static关键字 Java程序 编程风格&#xff08;驼峰式…

SAP从放弃到入门系列之abapGit更新与卸载

目录概览 概述一、更新1.1 独立版本1.2 开发者版本1.2.1 在线更新1.2.2 离线更新 1.3 更新版本常见问题 二、卸载abapGit 概述 我们就以更新abapGit为例,通过abapGit管理我们的代码其实操作时相似的&#xff0c;更新独立版本就有点像最原始的没有版本管理工具时的版本管理方式…

Elasticsearch中倒排索引、分词器、DSL语法使用介绍

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…