我有一个C++应用程序,根据经典Model-View-Controller pattern设计。该模型通过控制器接口由外部源通过Command pattern进行修改。这些命令由一个Action对象(及其派生物)表示。在MVC设计中撤销功能
现在我想能够撤消修改,但我的问题是我没有在我的控制器中的getters,只有setter。这似乎很合乎逻辑,因为没有理由有人应该能够通过控制器获得关于模型的信息。因此,我无法让Action对象存储模型的状态,因为他们无法访问它。
如何解决这个问题?我想保留我的应用程序尽可能扩展,我不太确定哪个选项最适合。我到目前为止的方法是:
- 将getter方法放在控制器中。这似乎违背了MVC模式。
- 给动作一个指向视图的指针。然后,该操作可以:
- 使用单个获取器来获取要修改的模型的特定元素的状态。
- 使用由查看器实现的Memento方法。
也许还有更好的方法来做到这一点?现在,成为最好的选择似乎是2,子选项1(子选项2,我可能存储更多的状态比撤消一个动作所需的更多)。
注:我知道还有关于如何实现撤消操作的其他问题。然而,我发现的唯一答案给了使用Command或Memento模式的建议。我知道这是最有可能的路要走。我所要求的是如何在MVC设计中尽可能地将其扩展为可扩展的。
[编辑]我不喜欢的纪念图案是它迫使我存储一个完整的状态。假设我的模型是一个1000x1000矩阵,我的命令是ChangeOneValueAtLocation。为了能够撤销它的更改,ChangeOneValueAtLocation对象只需要存储它正在改变的位置的先前值,但对于Memento来说这似乎不可能。我的模型越大,这个问题就会变得最大。
[编辑2]另一个问题我在本申请的特定情况中具有纪念品:每一个命令对象可以在模型执行方法,有,做完全相反(或可以很容易地被诱导的方法这样做)。这就是为什么我会觉得必须存储整个状态是一件很浪费的事情,应该不需要这样做,恢复单个命令非常简单,唯一的问题是让数据能够做到这一点。
此外,我不需要能够撤消一个特定的命令,只有在我的历史堆栈上的最顶层。
我决定采用这种方法,因为它可以让我轻松地将模型及其相关历史记录传输到异地客户端。将历史记录放入控制器会使这变得更加困难。此外,我的模型只有一个前端类,所以我不认为非原子撤销问题“sehe”提及会成为问题。 – Darhuuk 2011-04-20 12:11:21