我正在为一个民用工程应用程序编写一个结构建模工具。我有一个代表整个建筑的巨大模型类,其中包括节点、线元素、负载等的集合,这些也是自定义类。
我已经编写了一个撤销引擎,它会在每次修改模型后保存一个深度副本。现在我开始思考我是否可以用不同的方式编写代码。也许我可以保存每个修饰符操作的列表,而不是保存深层副本,并保存相应的反向修饰符。这样我就可以将反向修饰符应用于要撤消的当前模型,或者将修饰符应用到要重做的模型。
我可以想象你将如何执行简单的命令来改变对象的属性,等等。但是复杂的命令呢?比如在模型中插入新的节点对象,并添加一些line对象来保持对新节点的引用。
如何去实现它呢?
发布于 2008-09-08 14:00:58
我见过的大多数示例都使用Command-Pattern的变体来实现这一点。每个可撤消的用户操作都有自己的命令实例,其中包含执行操作和回滚操作所需的所有信息。然后,您可以维护已执行的所有命令的列表,并且可以逐个回滚这些命令。
发布于 2009-02-17 21:09:48
我认为当您处理OP所暗示的大小和范围的模型时,memento和command都是不实用的。它们可以工作,但维护和扩展会有很多工作要做。
对于这种类型的问题,我认为您需要内置对数据模型的支持,以支持模型中涉及的每个对象的差异检查点。我曾经这样做过一次,它工作得非常流畅。您必须做的最重要的事情是避免在模型中直接使用指针或引用。
每个对另一个对象的引用都使用某个标识符(如整数)。每当需要该对象时,都可以从表中查找该对象的当前定义。该表包含每个对象的链接列表,其中包含所有以前的版本,以及有关它们针对哪个检查点处于活动状态的信息。
实现撤消/重做很简单:执行您的操作并建立一个新的检查点;将所有对象版本回滚到以前的检查点。
它需要代码中的一些规则,但有许多优点:您不需要深度副本,因为您正在对模型状态进行差异存储;您可以通过重做次数或使用的内存来确定要使用的内存量(对于CAD模型而言非常重要);操作模型的函数具有非常高的可扩展性和低维护性,因为它们不需要执行任何操作来实现撤消/重做。
发布于 2008-09-08 15:00:39
如果您正在谈论GoF,那么Memento模式专门解决了撤销问题。
https://stackoverflow.com/questions/49755
复制相似问题