步骤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();
}
}
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。因为在备忘录模式中,我们保存了整个应用程序状态的深度拷贝。
使用备忘录模式的优缺点
它的优点在于其变更管理的表现非常好。
由于在备忘录模式中,我们保存了容器的状态,因此它是内存密集型的。这里你不得不对所有的对象和容器具有的属性进行深度拷贝。若你不能对其中任一个进行深度拷贝时将出现问题。