实施Memento pattern(用于撤消/重做)
时最佳用途收集Keep Mementos的女巫系列?
基本上,我需要这个(c = change,u = undo,r = redo):
0
*c
-1 0
*c
-2 -1 0
*c
-3 -2 -1 0
<u
-2 -1 0 1
*c
-3 -2 -1 0
变种:
答案 0 :(得分:1)
最后,我使用了LinkedList
Public Sub Add(ByVal item As T)
If _list.Count > 0 Then
If Me.IsFull Then
' we forgot (delete) the oldest state '
_list.RemoveFirst()
End If
' remove all the following the current items objects '
Dim lastNode As LinkedListNode(Of T) = _list.Last
While Not Object.ReferenceEquals(_currentNode, lastNode)
_list.RemoveLast()
lastNode = _list.Last
End While
End If
' add the new item and point current to it '
_currentNode = _list.AddLast(item)
End Sub
答案 1 :(得分:0)
撤消时,您将要恢复到最近覆盖的数据。因此,您想要使用的纪念品将是添加到该系列中的最后一个纪念品。由于堆栈是先进先出(LIFO),因此它们应该是您的意图的理想选择。
注意:您可能希望查看命令模式,因为它对实现撤消功能非常有用。
编辑:没注意到你想要重做。从你的堆栈弹出的东西将摆脱它,这样对你的目的没有多大用处。链接列表应该有效。
答案 2 :(得分:0)
您是否希望用户能够选择多个项目进行撤消或重做?
如果是这种情况,那么您可能希望使用通用List或ObservableCollection(如果是WPF / Silverlight),以便可以在UI中显示这些项。您可以使用两个列表:一个用于撤消,一个用于重做。
答案 3 :(得分:0)
使用双向链表。当用户使用撤销/重做时,他们可以多次索引状态(例如,做4个撤消,然后意识到他们走得太远并做重做)。单个堆栈或队列不支持该功能。
两个堆栈将支持撤销和重做,但我认为使用它们是一种浪费。一旦用户执行编辑(创建新的纪念品),所有重做纪念品将最终被删除。因此,大多数情况下,应用程序运行时将没有“重做”纪念品。
假设您已将垃圾收集标记为.net: 当用户进行编辑时,您将要对双向链接列表进行所有操作,将链接列表的头部引用设置为当前的纪念品。如果您使用堆栈,那么您将不得不创建一个新堆栈或弹出所有内容,以便gc释放重做纪念品。
答案 4 :(得分:0)
双头队列优选用于有效地支持撤消重做操作。当用户键入单词时,节点将插入到队列中,并且头指针指向当前位置。触发撤消操作时,只需将磁头移到上一个节点,然后在重做操作中将磁头指针移到列表中的下一个位置。如果进行编辑操作,请删除头右边的所有节点,并在头末端插入。这样,我们可以在 O(1)时间复杂度中执行撤消重做。