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 completo

Memento

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 completo

Por 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.