技术开发 频道

C#中使用备忘录模式实现Undo/Redo

  步骤5

  下面是UndoRedo类的实现:

Collapse  Copy Code
    
public class UndoRedo : IUndoRedo
    {
        Caretaker _Caretaker
= new Caretaker();
        MementoOriginator _MementoOriginator
= null;
        
public event EventHandler EnableDisableUndoRedoFeature;

        
public UndoRedo(Canvas container)
        {
            _MementoOriginator
= new MementoOriginator(container);

        }
        
public void Undo(int level)
        {
            Memento memento
= null;
            
for (int i = 1; i <= level; i++)
            {
                memento
= _Caretaker.getUndoMemento();
            }
            
if (memento != null)
            {
                _MementoOriginator.setMemento(memento);

            }
            
if (EnableDisableUndoRedoFeature != null)
            {
                EnableDisableUndoRedoFeature(
null, null);
            }
        }

        
public void Redo(int level)
        {
            Memento memento
= null;
            
for (int i = 1; i <= level; i++)
            {
                memento
= _Caretaker.getRedoMemento();
            }
            
if (memento != null)
            {
                _MementoOriginator.setMemento(memento);

            }
            
if (EnableDisableUndoRedoFeature != null)
            {
                EnableDisableUndoRedoFeature(
null, null);
            }
        }

        
public void SetStateForUndoRedo()
        {
            Memento memento
= _MementoOriginator.getMemento();
            _Caretaker.InsertMementoForUndoRedo(memento);
            
if(EnableDisableUndoRedoFeature != null)
            {
                EnableDisableUndoRedoFeature(
null,null);
            }
        }

        
public bool IsUndoPossible()
        {
            
return _Caretaker.IsUndoPossible();

        }
        
public bool IsRedoPossible()
        {
          
return  _Caretaker.IsRedoPossible();
        }
    }

  级别有多高,在Undo方法中,我们就执行UndoOperation多少次。在每次的Undo操作中,我们从Caretaker获取UndoMemento并利用MementoOriginator将Undomemento设置给画布。同样的,在Redo方法中,我们就执行RedoOperation多少次。在每次的RedoOperation中,我们从Caretaker获取RedoMemento并利用MementoOriginator获取当前备忘录(状态),然后将当前备忘录(状态)插入到Caretaker以支持Undo/Redo。

  步骤6

  在该应用程序每次操作后,我们调用UndoRedo类的SetStateForUndoRedo()方法使UndoRedo操作可用。当用户界面上点击Undo时,我们调用UndoRedo类的Undo方法而当用户界面上点击Redo时,我们调用UndoRedo类的redo方法。

  这里,我们没有明确设置Undo栈和Redo栈的大小,因此,应用程序能具有的状态数目取决于系统的内存。

  使用备忘录模式时的变更管理

  在备忘录模式中,如果你想要添加新的操作,一般来说你不需要在Undo/Redo代码中作任何改动就可以使得操作能Undo/Redo。因为在备忘录模式中,我们保存了整个应用程序状态的深度拷贝。
使用备忘录模式的优缺点

  它的优点在于其变更管理的表现非常好。

  由于在备忘录模式中,我们保存了容器的状态,因此它是内存密集型的。这里你不得不对所有的对象和容器具有的属性进行深度拷贝。若你不能对其中任一个进行深度拷贝时将出现问题。

1
相关文章