O padrão Memento é um padrão de design comportamental que tem como objetivo principal permitir a captura e o armazenamento do estado atual de um objeto de maneira a permitir a restauração desse estado posteriormente. O padrão Memento resolve uma série de problemas relacionados ao gerenciamento de estados:
-
Restauração de Estados Anteriores: Em muitos sistemas, pode ser necessário reverter um objeto para um estado anterior, seja por causa de uma operação que precisa ser desfeita (como um comando "undo") ou por causa de erros que exigem a recuperação de um estado estável.
-
Encapsulamento de Estados Internos: O Memento permite que o estado interno de um objeto seja salvo e restaurado sem violar o encapsulamento. Isso significa que o objeto não precisa expor suas propriedades internas apenas para possibilitar a restauração de seu estado.
-
Simplificação do Objeto de Origem: Ao delegar a função de armazenamento de estado para o Memento, o objeto de origem (o objeto cujo estado está sendo salvo) permanece mais simples, sem a necessidade de gerenciar os estados passados.
Como Funciona
O padrão Memento envolve três componentes principais:
- Originator: O objeto cujo estado interno precisa ser salvo e restaurado. Ele cria um memento contendo uma fotografia de seu estado interno atual.
- Memento: Um objeto que armazena o estado interno do originator. Possui métodos para obter e definir o estado do originator, mas esses métodos são acessíveis apenas pelo originator.
- Caretaker: Responsável por manter o memento. Ele solicita um memento do originator para salvar o estado atual e passa o memento de volta ao originator para restaurar um estado anterior. O caretaker não modifica ou examina o conteúdo do memento.
Exemplo
Um exemplo clássico do uso do padrão Memento é em editores de texto ou gráficos, onde a funcionalidade "desfazer" é essencial. Cada ação do usuário que altera o estado do documento pode ser salva como um memento. Se o usuário decidir desfazer uma ação, o editor pode restaurar o estado do documento para o estado capturado no memento correspondente.
Exemplo de implementação
Vamos criar um exemplo simples do padrão Memento em Java. Vamos desenvolver um editor de texto simples que permite salvar e restaurar o estado do texto.
Classe Memento
Primeiro, definimos a classe Memento que armazena o estado do editor:
public class Memento {
private String estado;
public Memento(String estado) {
this.estado = estado;
}
public String getEstado() {
return estado;
}
}Classe Originator
Agora, criamos a classe EditorTexto que é o originator. Ela pode criar e restaurar mementos:
public class EditorTexto {
private String conteudo;
public void set(String conteudo) {
this.conteudo = conteudo;
}
public Memento salvarParaMemento() {
return new Memento(conteudo);
}
public void restaurarDeMemento(Memento memento) {
conteudo = memento.getEstado();
}
public String toString() {
return conteudo;
}
}Classe Caretaker
A classe Caretaker mantém um histórico de mementos:
import java.util.ArrayList;
import java.util.List;
public class Caretaker {
private List<Memento> estadosSalvos = new ArrayList<>();
public void adicionarMemento(Memento m) {
estadosSalvos.add(m);
}
public Memento getMemento(int index) {
return estadosSalvos.get(index);
}
}Testando o Padrão Memento
Por fim, usamos o padrão Memento para salvar e restaurar o estado do editor:
public class Main {
public static void main(String[] args) {
EditorTexto editor = new EditorTexto();
Caretaker caretaker = new Caretaker();
editor.set("Estado 1");
caretaker.adicionarMemento(editor.salvarParaMemento());
editor.set("Estado 2");
caretaker.adicionarMemento(editor.salvarParaMemento());
editor.set("Estado 3");
// Restaurando para o estado 1
editor.restaurarDeMemento(caretaker.getMemento(0));
System.out.println(editor);
}
}Neste exemplo, a cada alteração no conteúdo do EditorTexto, um novo estado é salvo em um Memento e armazenado pelo Caretaker. Podemos então restaurar qualquer estado anterior do EditorTexto usando um Memento específico. Isso demonstra como o padrão Memento permite salvar e restaurar estados de um objeto sem violar o encapsulamento.