【发布时间】:2011-08-07 09:58:21
【问题描述】:
我有一个根据经典 Model-View-Controller pattern 设计的 C++ 应用程序。该模型通过控制器接口由外部源通过Command pattern 进行修改。这些命令由一个 Action 对象(及其衍生物)表示。
现在我希望能够撤消修改,但我的问题是我的控制器中没有 getter,只有 setter。这似乎很合乎逻辑,因为没有理由有人应该能够通过控制器获取有关模型的信息。因此,我不能让我的 Action 对象存储模型的状态,因为它们无权访问它。
如何解决这个问题?我想让我的应用程序尽可能可扩展,但我不太确定哪个选项最适合。到目前为止,我想到的方法是:
- 将 getter 方法放入控制器中。这似乎违背了 MVC 模式。
- 为操作提供指向视图的指针。然后,Action 可以:
- 使用单独的 getter 获取要修改的模型的特定元素的状态。
- 使用由查看器实现的Memento 方法。
也许有更好的方法来做到这一点?现在,最好的选择似乎是 2,子选项 1(使用子选项 2,我很可能存储比撤消一个操作所需的更多的状态)。
注意:我知道关于如何实现撤消操作还有其他问题。但是,我找到的唯一答案给出了使用命令或备忘录模式的建议。我知道这很可能是要走的路。我要问的是如何在 MVC 设计中尽可能干净和可扩展地集成它。
[编辑] 我不喜欢 Memento 模式的地方在于它迫使我存储完整的状态。假设我的模型是 1000x1000 矩阵,我的命令是 ChangeOneValueAtLocation。为了能够撤消其更改,ChangeOneValueAtLocation 对象只需要存储它正在更改的位置的先前值,但对于 Memento,这似乎是不可能的。我的模型越大,这个问题就越大。
[Edit 2] Memento 在这个应用程序的特定情况下遇到的另一个问题:对于一个 Command 对象可以在模型上执行的每个方法,都有一个方法完全相反(或者可以很容易被哄着这样做)。这就是为什么我觉得必须存储整个状态是一种浪费,应该没有必要,恢复单个命令非常简单,唯一的问题是获取数据才能做到这一点。
另外,我不需要能够撤消特定命令,只需撤消我历史堆栈中最顶部的命令。
【问题讨论】:
标签: c++ design-patterns