3

我正在为某种二叉树结构开发一个编辑器,我需要一个撤消功能。我考虑过使用命令模式来实现这一点。但是,我还没有找到一种方法来将命令模式与我的二叉树结构一起使用。

二叉树结构是通过指针组成的。所以一个节点知道它的父节点和子节点。当我现在想添加一个节点时,我会NodeAdd以父节点作为参数构造一个对象并将其传递给UndoStack. 为了删除现有节点,将使用指向as 参数的指针NodeRemove将对象传递给。两者,and都必须实现and (当对象放在时调用where )。UndoStackNodeNodeAddNodeRemoveundo()redo()redo()UndoStack

我面临的问题是,处理删除节点然后撤消添加同一节点的情况:

  1. 重做节点添加
  2. 重做节点删除
  3. 撤消节点删除
  4. 撤消节点添加

一旦执行了重做 NodeRemoveNode ,对象就会被销毁。在undo NodeRemoveNode中,可以再次构造一个新对象,但无法执行undo NodeAdd,因为它没有指向新构造的指针Node

我想我试图以错误的方式使用命令模式。我可能应该Node在命令的构造函数/析构函数中而不是在undo()/中销毁或构造对象redo()。不幸的是,我不知道如何使用这种结构来做到这一点,我能找到的所有示例和建议都与文本编辑或编辑没有带有指针的动态结构的东西有关。

任何想法如何解决这个问题?

4

3 回答 3

1

命令模式可能不足以用于撤消。对于撤消,您应该使用 memento 模式。

于 2012-10-26T13:59:51.510 回答
1

一种选择是让您的Command对象通过某个唯一标识符(例如表示为 a 的索引size_t)而不是通过内存地址来引用它们的操作数,正如您所发现的那样,内存地址可能会波动。

然后,通过维护某处(例如,例如unordered_map< size_t, Node* >静态成员),您的对象可以获得给定的当前实施例并根据需要添加/删除/操作它。NodeCommandNode

于 2012-10-26T14:28:58.470 回答
0

模式可以组合,甚至在它们内部。给你的命令一个执行方法和一个撤销方法。调用命令时,将实例放入双向责任链中,具有撤消和重做方向和方法。

于 2012-10-26T19:20:18.447 回答