如何在文本编辑器中设计撤消和重做?
2022-09-02 23:52:28
我的项目的一部分是编写一个文本编辑器,用于键入一些规则,编译我的应用程序并运行它。编写编译器是结束和发布测试版。在最终版本中,我们必须将撤消和重做添加到文本编辑器中。我使用一个文件并定期将其保存为文本编辑器。如何设计撤消和重做到我的文本编辑器?文件的持久性结构发生了什么变化?
我的项目的一部分是编写一个文本编辑器,用于键入一些规则,编译我的应用程序并运行它。编写编译器是结束和发布测试版。在最终版本中,我们必须将撤消和重做添加到文本编辑器中。我使用一个文件并定期将其保存为文本编辑器。如何设计撤消和重做到我的文本编辑器?文件的持久性结构发生了什么变化?
您可以将操作建模为命令,并将其保存在两个堆栈中。一个用于撤消,另一个用于重做。您可以组合命令以创建更多高级命令,例如,当您要撤消宏的操作时;或者,如果要将单个单词或短语的各个击键组合到一个操作中。
编辑器中的每个操作(或重做操作)都会生成一个新的撤消命令,该命令进入撤消堆栈(并清除重做堆栈)。每个撤消操作都会生成相应的重做命令,该命令进入重做堆栈。
正如derekerdmann的评论中提到的,您还可以将撤消和重做命令组合成一种类型的命令,该命令知道如何撤消和重做其操作。
基本上有两种好方法可以做到这一点:
“命令”设计模式
在不可变对象上仅使用OO,其中所有内容都只是由不可变对象组成的不可变对象,这些对象本身就是不可变对象(这并不常见,但如果正确完成,则非常优雅)
与朴素命令或朴素的撤消/重做相比,使用OO而不是不可变对象的优势在于,您无需考虑太多:无需“撤消”操作的效果,也无需“重放”所有命令。您所需要的只是一个指向大量不可变对象列表的指针。
由于对象是不可变的,因此所有“状态”都可以非常轻量级,因为您可以在任何状态下缓存/重用大多数对象。
“不可变对象上的OO”是一颗纯粹的宝石。可能在另一个10年之前不会成为主流;)
P.S:在不可变对象上执行 OO 也极大地简化了并发编程。