首页 > 其他分享 >设计模式备忘录+命令模式实现Word撤销恢复操作

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

时间:2023-09-03 22:02:54浏览次数:33  
标签:文本 Word 命令 对象 撤销 备忘录 文档 设计模式



文章目录

  • 前言
  • 思路
  • 代码实现
  • 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());  // 输出:""
    }

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

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

uml类图

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

总结

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

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

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

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

  1. 提高代码的可维护性和可扩展性:设计模式使代码结构更清晰、更易于理解和维护。模式中定义了明确的角色和关系,使代码具有良好的组织结构和可扩展性。
  2. 复用性增加:设计模式通过提供通用的解决方案,使得代码可以在不同场景下被重复使用。这避免了重复编写相似的代码,提高了开发效率。
  3. 降低耦合度:设计模式通过明确角色和关系,将系统中各组件之间的依赖关系降到最低。这样,当需求变化或者需要修改某一个组件时,对其他组件的影响最小,易于维护和扩展。
  4. 提高代码的可测试性:设计模式将逻辑分离开来,使得每个模块可以独立地进行测试,便于编写单元测试和集成测试。


标签:文本,Word,命令,对象,撤销,备忘录,文档,设计模式
From: https://blog.51cto.com/u_15918766/7343554

相关文章

  • 设计模式行为模式-访问者模式
    文章目录介绍基本原理1.定义访问者模式2.角色及其职责2.1元素(Element)2.2具体元素(ConcreteElement)2.3访问者(Visitor)2.4具体访问者(ConcreteVisitor)2.5对象结构(ObjectStructure)3.访问者模式的工作流程适用场景1.对象结构稳定,但需要经常增加新的操作2.处理复杂的对象结构,并......
  • 设计模式-原型模式详解
    文章目录前言理论基础1.原型模式定义2.原型模式角色3.原型模式工作过程4.原型模式的优缺点实战应用1.原型模式适用场景2.原型模式实现步骤3.原型模式与单例模式的区别原型模式的变体1.带有原型管理器的原型模式2.懒汉式单例模式的原型模式实现3.细粒度原型模式总结前言......
  • 设计模式-装饰模式
    文章目录一、简介二、基本概念三、装饰模式的结构和实现类图解析:装饰器的实现方式继承实现:组合实现:继承和组合对比四、装饰模式的应用场景五、与其他模式的关系六、总结一、简介装饰模式是一种结构型设计模式,它允许动态地向对象添加额外的功能。二、基本概念装饰模式定义:在不改变......
  • 设计模式-迭代器
    文章目录1.引言1.1概述1.2设计模式1.3迭代器模式的应用场景1.4迭代器模式的作用2.基本概念2.1迭代器Iterator2.2聚合Aggregate2.3具体聚合ConcreteAggregate3.Java实现迭代器模式3.1Java集合框架3.2Java迭代器接口3.3Java迭代器模式实现示例4.迭代器模式的优......
  • Go 设计模式中策略模式
    鱼弦:全栈领域创作新星创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)  在Go设计模式中,策略模式是一种行为型模式,用于在运行时选择算法的行为。策略模式将不同的算法封装成各自的策略对象,并使得这些策略对象......
  • Go 设计模式中访问者模式
    鱼弦:全栈领域创作新星创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)在Go设计模式中,访问者模式(VisitorPattern)是一种行为型模式,用于将算法与数据结构分离,使得算法可以独立地操作数据结构的不同元素,同时遵循......
  • Python顺序读取word文档中的文本与表格
    importosimportdocxfromdocx.documentimportDocumentfromdocx.oxml.tableimportCT_Tblfromdocx.oxml.text.paragraphimportCT_Pfromdocx.tableimport_Cell,Tablefromdocx.text.paragraphimportParagraphdefiter_block_items(parent):"......
  • python办公自动化(6)——读取word文档
     #使用import导入os模块importos#将乔老师的答题卡文件夹路径/Users/qiao/answerKey赋值给变量allKeyPathallKeyPath="/Users/qiao/answerKey"#使用os.listdir()函数获取该路径下所有的文件,并赋值给变量allItemsallItems=os.listdir(allKeyPath)#定义一个......
  • 设计模式:通俗易懂版
    ......
  • 两个例子理解js设计模式中的【适配器模式】
    适配器模式的精髓:如果现有的接口已经能够正常工作,那我们就永远不会用上适配器模式。适配器模式是一种“亡羊补牢”的模式,没有人会在程序的设计之初就使用它。因为没有人可以完全预料到未来的事情,也许现在好好工作的接口,未来的某天却不再适用于新系统,那么我们可以用适配器模式把旧......