如何用命令模式实现长尾词的Word撤销恢复操作备忘录设计模式?

2026-04-19 07:472阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2503个文字,预计阅读时间需要11分钟。

如何用命令模式实现长尾词的Word撤销恢复操作备忘录设计模式?

文章目录+前言+思路+代码实现+UML类图+总结+前言+最近学习的行为型模式,学到了备忘录模式。这种模式可以记录一个对象的特定状态,用于后续的复用。比如,我们可以记录一个对象的某些属性值,以便在下一次使用时恢复到之前的状态。这样方便了我们在需要时快速回到之前的状态,提高了代码的可维护性和复用性。



文章目录

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

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

如何用命令模式实现长尾词的Word撤销恢复操作备忘录设计模式?

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


本文共计2503个文字,预计阅读时间需要11分钟。

如何用命令模式实现长尾词的Word撤销恢复操作备忘录设计模式?

文章目录+前言+思路+代码实现+UML类图+总结+前言+最近学习的行为型模式,学到了备忘录模式。这种模式可以记录一个对象的特定状态,用于后续的复用。比如,我们可以记录一个对象的某些属性值,以便在下一次使用时恢复到之前的状态。这样方便了我们在需要时快速回到之前的状态,提高了代码的可维护性和复用性。



文章目录

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

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

如何用命令模式实现长尾词的Word撤销恢复操作备忘录设计模式?

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