"Memento"和"Command"设计模式有什么区别?

6
我成功地使用Java编写了一个纸牌游戏,现在被要求在我的设计上实现撤销/重做功能。
我的计划是存储用户执行的移动列表或堆栈,如果用户想要撤销,则会 1. 检查用户是否可以撤销(即列表或堆栈中有移动),然后 2. 反转我存储的最后两个移动(即“从”移动和“到”移动)。
对于重做,我将根据用户执行撤销操作的深度重新执行移动(例如,如果他们按两次撤销,那么我至少会在我的列表或堆栈中向下移动(列表大小-4))。
我认为它们将在接口中实现,如下所示:
public interface UndoRedo {
    void undo();
    void redo();
 }

我是在实现备忘录模式,还是命令模式,或两者都不是?我对这两种设计模式在此游戏的撤消/重做上的表现形式感到困惑。我也是Java面向对象编程和设计模式的初学者。


现在我被要求实现... - Fuhrmanator
3个回答

10
根据您的描述,您似乎实现了命令模式。
命令模式捕获执行某些操作所需的所有信息(不一定是撤销此操作)。 您的移动基本上就是命令。
备忘录是一种存储状态以便恢复的方法。假设您有一个名为GameState的类,它表示游戏的当前状态。如果您的GameState具有像GameStateBackup createBackup()和restoreFromBackup(GameStateBackup)这样的方法,则正在实现Memento。
考虑下象棋游戏,您希望能够撤消最后x个移动。
一种方法是记录所有移动。然后您可以“撤消”移动。或者简单地“重播”前n-x个移动。那将是命令方式。
另一种方法是保存游戏的最后x个状态(并能够恢复它们)。这是备忘录方法。
您实际上可以同时使用两种模式。例如,在无法实现“撤消”时,您可以在每次移动之前/之后记录游戏状态以使移动可撤消。

6
如果您通过在状态上执行命令来撤消/重做,则是命令模式。如果您通过从状态缓存中替换状态来撤消/重做,则是备忘录模式。
“撤消/重做”中命令模式和备忘录模式的区别在于,在命令模式中,您按照更改状态属性的相同顺序重新执行命令;而在备忘录模式中,您通过从缓存/存储中检索来完全替换状态。 Python设计模式:ASIN B08XLJ8Z2J

谢谢! - William Le

0

都不是。你正在将先前的输入作为状态存储,并允许对数据进行操作。

Memento 为确定性函数的每个唯一输入存储计算值,并在再次看到相同的输入时返回存储的值。

Command 将执行代码及其输入捆绑为单个对象,稍后可以通过将输入传递给可执行文件来执行它。

它与 Command 接近,但似乎不像 Command,因为它不是独立的异步操作。


1
Memento的描述暗示它只是缓存,这是一种过度简化。此外,我认为Command的描述应该以“将_object_传递给_executor_”结束。 - jaco0646

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