如何实现撤销功能?

9
在我的应用程序中,我想提供给用户一个小型的撤销功能。用户可以撤销的操作非常少。特别是以下操作:
  • 在对象上添加注释
  • 给对象上色
  • 用字符串标记对象
现在我考虑如何实现这个功能。我首先想到了一个Action类,它是用户可以执行的3种不同操作的抽象基类。每次用户执行其中一项操作时,都会创建一个适当的Action子类的新实例,并将其插入到包含所有操作的列表中。
每当用户想要撤销某些操作时,列表将显示给用户,他可以选择要撤销哪个操作。
现在我在思考这样一个操作对象中必须存储什么:
  • 操作之前对象的状态
  • 实际执行的操作(例如添加到对象注释的字符串)
我不确定这是否足够。我还考虑了一些其他方面,比如按时间顺序排序,但由于列表可以保持时间顺序正确,所以这不是必需的。
还有其他需要考虑的事情吗?

1
在《设计模式》(GOF)中搜索备忘录模式。 - pastjean
1
请参见此处:https://dev59.com/w3VD5IYBdhLWcg3wNY1Z - Steve Townsend
5个回答

17

撤消/重做通常使用命令模式(Command Pattern)实现。可以使用Action类作为此基础,但是每个命令内需要有“执行(do)”和“撤销(undo)”操作。 这里有一个实际例子

建议将已执行的命令存储在堆栈中,因为这样更容易实现,用户也更容易跟踪。


9
你可以像这样做一些简单的事情:
Stack<Action> undoStack = new Stack<Action>();    

void ChangeColor(Color color)
{
    var original = this.Object.Color;
    undoStack.Push(() => this.Object.Color = original);
    this.Object.Color = color;
}

我喜欢这个。从来没有想过存储实际的操作...非常好。 - Chris Pfohl

5

2

对于撤销功能的正确和经过验证的实现,可以使用命令模式。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接