2010-02-25 40 views
5

什麼是最好的時候實施Memento pattern(用於撤消/重做)使用Memento撤銷/重做:堆棧,隊列還是隻是LinkedList?

在女巫收集保存紀念品?

基本上,我需要這個(c =更改,U =撤消,R =重做):

    0 
        *c 
      -1 0 
        *c 
     -2 -1 0 
        *c 
-3 -2 -1 0 
        <u 
     -2 -1 0 1 
        *c 
-3 -2 -1 0 

變種:

  • LinkedList的 - 可能在原則上,也許不是最優化。
  • 隊列 - 不適用於此任務IMO。
  • 堆棧 - 不適用於撤消和重做;
  • Double Stack - 可能是最優的,但無法控制撤消最大尺寸。
+0

這是功課? – 2010-02-25 11:08:33

+0

不,這是一個項目。我們實現撤銷/重做功能。與這種情況的堆棧和隊列可用性有點混淆。 – serhio 2010-02-25 11:21:10

回答

1

最後,我用鏈表

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 
0

當你撤消你將要恢復到最近覆蓋的數據。所以你想使用的紀念品將是最後一個添加到集合中的。由於堆棧是先進先出(LIFO),它們應該適合您的意圖。

注意:您可能希望查看命令模式,因爲它對於實現撤消功能非常有用。

編輯:沒有注意到你想重做。從堆棧中彈出的東西將擺脫它,所以不會爲你的目的使用太多。鏈接列表應該有效。

+0

是的,但紀念似乎是夠好的。但是,我有一個非常大的對象來「記憶」,所以它將與Clone()實現一起工作。 – serhio 2010-02-25 11:23:14

+0

在上面的修改中回覆了您的評論。沒有通知你想要重做 – sfg 2010-02-25 11:39:07

+0

LinkedList可以在After和Before之前添加一些元素,所以它不是可取的。堆棧 - 當我撤消時,我應該能夠重做該操作。所以,「out」元素不應該是「明確的」。 – serhio 2010-02-25 11:58:11

0

您是否希望用戶能夠選擇多個項目進行撤消或重做?

如果是這種情況,那麼您會希望使用通用List或ObservableCollection(如果WPF/Silverlight),以便項目可以顯示在UI中。您可以使用兩個列表:一個用於撤消,一個用於重做。

+0

不,只有一個撤銷和重做按鈕。 – serhio 2010-02-26 09:20:49

0

使用雙向鏈表。當用戶使用撤銷/重做時,他們可能會多次索引狀態(例如,做4次撤銷,然後意識到他們做得太過分並重做)。單個堆棧或隊列將不支持該功能。

兩個堆棧將支持撤消和重做,但我認爲使用它們有點浪費。只要用戶執行編輯(即創建新紀念品),所有重做紀念品將最終被刪除。所以,大多數情況下,應用程序運行時不會有'重做'紀念品。

假設你有垃圾收集,因爲你標記它.net: 當用戶進行編輯,所有你必須做的雙鏈表設置鏈表的頭參考當前紀念品。如果您使用堆棧,那麼您必須創建一個新的堆棧或將所有內容全部關閉以便gc釋放重做紀念碑。