Você já travou ao criar um botão de “Desfazer” em um app iOS?
Em um editor de texto, permitir que o usuário desfaça a edição mais recente começa pela questão de como manter o estado anterior.
Fazer backup das propriedades internas do objeto em vários lugares deixa o código bagunçado rapidamente.
O padrão Memento do Swift é perfeito para isso. Hoje, vou mostrar, com código e baseando-me na minha experiência, como salvar e restaurar o estado de um objeto com elegância usando esse padrão.
O padrão Memento armazena externamente o estado interno de um objeto sem quebrar o encapsulamento e permite restaurá-lo depois.
Em uma frase: “tirar um snapshot”. Ele é a base de recursos como Undo, salvamento de jogos e armazenamento temporário de formulários.
O que é o padrão Memento? Comece pelos três papéis 🧩
O padrão Memento tem exatamente três personagens. Entendendo estes, você já percorreu metade do caminho.
- Originator (objeto originador): O protagonista que possui o estado. Salva seu estado como um Memento e o restaura a partir dele.
- Memento: Um snapshot que contém o estado em um momento específico. O ideal é que seu conteúdo não mude depois de criado.
- Caretaker (gerenciador): Responsável por armazenar os Memento. Normalmente, esse papel é desempenhado por uma pilha de Undo.
O ponto principal é que o gerenciador não olha dentro do Memento.
O gerenciador apenas recebe os snapshots, empilha-os e os devolve quando necessário. Só o objeto originador conhece sua estrutura interna.
Assim, o encapsulamento é preservado. Essa é a maior vantagem do padrão Memento.
Como implementar o padrão Memento em Swift?
Vamos usar um editor de texto simples como exemplo. Primeiro, definimos o Memento e o objeto originador.
A seguir estão o Memento que armazena o estado e o objeto originador que o cria e restaura.
// Snapshot do estado — não alterar depois de criar let
struct EditorMemento {
let text: String
}
final class TextEditor {
var text: String = ""
func save() -> EditorMemento { EditorMemento(text: text) } // Salvar
func restore(_ memento: EditorMemento) { text = memento.text } // Restaurar
}
save()tira um snapshot do estado atual, enquanto restore(_:)restaura o snapshot recebido.
O ponto principal é deixar a propriedade de EditorMementocomo let, para que o estado salvo não seja alterado depois.
Na prática: criando o recurso de Undo ⏪
Agora vamos adicionar o gerenciador, ou seja, a pilha de Undo. Ele acumula os Memento criados anteriormente.
final class UndoManager {
private var history: [EditorMemento] = []
func backup(_ memento: EditorMemento) { history.append(memento) }
func undo() -> EditorMemento? { history.popLast() } // Remover o estado mais recente
}
O fluxo real funciona assim.
Antes de o usuário editar o texto, salvamos o estado atual com backup.
Quando o usuário toca em “Desfazer”, undoretira o último snapshot, e o objeto originador o restore.
Depois de integrar tudo, a lógica de edição e a de salvamento ficaram bem separadas, deixando o código muito mais limpo.
Mesmo com vários tipos de edição misturados, como adicionar ou excluir texto e alterar a formatação, o método de salvamento continuou unificado, facilitando a manutenção.
Dicas para usar como Swift: aproveitando Codable e struct
Muitos artigos explicam o padrão Memento com base em linguagens como Java. No Swift, aproveitar as características da linguagem torna tudo muito mais simples.
Primeiro, structcombina melhor com Memento do que class. Como é um tipo por valor, sua cópia se torna um snapshot independente no momento em que é criada. Isso reduz a preocupação de o original mudar por causa de referências interligadas.
Segundo, adotar Codableno Memento facilita salvar o estado em um arquivo ou no UserDefaults. Você pode evoluí-lo para um recurso de salvamento que persiste mesmo após fechar e abrir o app.
Terceiro, se você usa UIKit, vale verificar primeiro a classe de sistema existente UndoManager. Antes de implementar algo próprio, é importante conhecer as ferramentas padrão.
Perguntas frequentes (Q&A)
P. Não posso simplesmente fazer backup em variáveis?
Em casos simples, pode. Mas, quando há vários estados ou a lógica de salvar e restaurar fica complexa, o código de backup espalhado vira um terreno fértil para bugs. O padrão Memento concentra tudo em um só lugar.
P. Isso não vai consumir memória demais?
É verdade. Acumular snapshots indefinidamente aumenta o consumo de memória. Por isso, na prática, é comum limitar o histórico a cerca de 20–50 itens ou salvar apenas as partes alteradas.
O padrão Memento pode ter um nome estranho, mas na prática é apenas a ideia simples de “tirar snapshots e voltar atrás”.
Se você está pensando em implementar Undo ou salvamento temporário, experimente acompanhar o código de exemplo de hoje. Você vai pegar rapidamente o jeito de trabalhar com estado preservando o encapsulamento. Boa sorte! 😊

