问题描述
我正在编写用于民用启动应用程序的结构建模工具.我有一个代表整个建筑物的巨大模型类,其中包括节点,线元素,负载等的集合,它们也是自定义类.
我已经编码了一个撤消引擎,该引擎在每次修改模型后都保存了深层复制.现在,我开始思考是否可以使用不同的编码.我可以使用相应的反向修饰符保存每个修饰符动作的列表,而不是保存深层探测器.因此,我可以将反向修饰符应用于当前模型中的撤消,或者将修饰符应用于重做.
我可以想象您将如何执行更改对象属性等的简单命令.但是复杂命令呢?就像将新节点对象插入模型并添加一些线路对象,以保持对新节点的引用.
如何实施?
推荐答案
我见过的大多数示例都使用 command-pattern "> command-pattern 用于这个.每个不愉快的用户行动都会获得自己的命令实例,其中包含所有信息来执行操作并将其滚动.然后,您可以维护所有已执行的命令的列表,并且可以一个一个一个.
.其他推荐答案
我认为,当您处理OP所暗示的大小和范围的模型时,纪念品和命令都是不切实际的.他们会工作,但要维护和扩展将是很多工作.
对于此类问题,我认为您需要构建支持数据模型,以支持模型中涉及的每个对象的差异检查点.我已经做过一次了,而且工作非常光滑.您要做的最大的事情是避免在模型中直接使用指针或参考.
对另一个对象的每个引用都使用某些标识符(例如整数).每当需要对象时,您就可以从表中查找对象的当前定义.该表包含一个包含所有先前版本的每个对象的链接列表,以及有关它们活动的检查点的信息.
实施撤消/重做很简单:采取行动并建立一个新的检查点;回滚所有对象版本到上一个检查点.
它在代码中需要一些纪律,但具有许多优势:您不需要深入副本,因为您正在对模型状态进行不同的存储;您可以按所用的重做或内存来范围范围范围范围(对于CAD型号之类的事物)范围(对于CAD型号之类的东西来说非常重要);对于在模型上运行的功能的非常可扩展和低维护,因为它们不需要做任何实现撤消/重做的事情.
其他推荐答案
如果您在谈论Gof,则 Memento 模式专门解决了<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<./p>
问题描述
I'm writing a structural modeling tool for a civil enginering application. I have one huge model class representing the entire building, which include collections of nodes, line elements, loads, etc. which are also custom classes.
I have already coded an undo engine which saves a deep-copy after each modification to the model. Now I started thinking if I could have coded differently. Instead of saving the deep-copies, I could perhaps save a list of each modifier action with a corresponding reverse modifier. So that I could apply the reverse modifiers to the current model to undo, or the modifiers to redo.
I can imagine how you would carry out simple commands that change object properties, etc. But how about complex commands? Like inserting new node objects to the model and adding some line objects which keep references to the new nodes.
How would one go about implementing that?
推荐答案
Most examples I've seen use a variant of the Command-Pattern for this. Every user-action that's undoable gets its own command instance with all the information to execute the action and roll it back. You can then maintain a list of all the commands that have been executed and you can roll them back one by one.
其他推荐答案
I think both memento and command are not practical when you are dealing with a model of the size and scope that the OP implies. They would work, but it would be a lot of work to maintain and extend.
For this type of problem, I think you need to build in support to your data model to support differential checkpoints for every object involved in the model. I've done this once and it worked very slick. The biggest thing you have to do is avoid the direct use of pointers or references in the model.
Every reference to another object uses some identifier (like an integer). Whenever the object is needed, you lookup the current definition of the object from a table. The table contains a linked list for each object that contains all the previous versions, along with information regarding which checkpoint they were active for.
Implementing undo/redo is simple: Do your action and establish a new checkpoint; rollback all object versions to the previous checkpoint.
It takes some discipline in the code, but has many advantages: you don't need deep copies since you are doing differential storage of the model state; you can scope the amount of memory you want to use (very important for things like CAD models) by either number of redos or memory used; very scalable and low-maintenance for the functions that operate on the model since they don't need to do anything to implement undo/redo.
其他推荐答案
If you're talking GoF, the Memento pattern specifically addresses undo.