Command × Memento
Dois padrões que costumam ser trocados um pelo outro, e o que de fato os separa.
Em uma frase
Os dois aparecem no undo — e é aí que se confundem. Command encapsula a operação (fazer / desfazer); Memento guarda o estado anterior para restaurar. Um é verbo; o outro é foto.
Critério a critério
O que é serializado?
- Command
- A intenção: 'apagar estas linhas', 'aplicar este estilo' — com execute e undo.
- Memento
- Um snapshot opaco do objeto: o estado de antes, sem expor a estrutura interna.
Quem sabe desfazer?
- Command
- O próprio comando: ele conhece a operação inversa ou o delta que aplicou.
- Memento
- O originador: recebe o memento e se restaura; o cuidado externo não mexer no snapshot.
Quanto custa a memória?
- Command
- Em geral barato: guarda parâmetros e, no máximo, o que a operação alterou.
- Memento
- Pode ser caro: uma cópia inteira do estado a cada passo, se não for preguiçoso.
Serve para replay?
- Command
- Sim — a fila de comandos é um log de intenções reexecutável.
- Memento
- Não diretamente: o memento restaura um ponto, não narra o caminho.
Quando a API interna muda?
- Command
- Os comandos antigos podem quebrar se dependiam de detalhes internos.
- Memento
- O memento continua opaco: só o originador interpreta o formato.
Quando escolher cada um
Command
As ações são bem definidas, o undo é a operação inversa, e você quer histórico, macro ou fila de trabalho.
Ver o conceito completoMemento
O estado interno é complexo demais para inverter operação a operação, e um snapshot (mesmo preguiçoso) é mais simples e seguro.
Ver o conceito completoPor que confundem
Chamar de Memento qualquer coisa que 'lembra o passado' no undo. Se o objeto guardado é 'DeleteTextCommand' com execute/undo, é Command. Se é um blob que o editor engole para voltar no tempo sem saber o que mudou, é Memento. Editores sérios misturam os dois: comandos na UI, mementos (ou patches) por baixo.