Padrão de Projeto Memento
Kleinner Farias e Raphael do Vale
© LES/PUC-Rio
Agenda
• Intenção
• Motivação
• Aplicabilidade
• Estrutura
• Participantes
• Conseqüências
• Implementação
• Exemplo
© LES/PUC-Rio
Intenção
• Sem violar o encapsulamento, capturar e externalizar um
estado interno de um objeto, de maneira que o objeto possa
ser restaurando para este estado mais tarde.
© LES/PUC-Rio
Motivação
• Algumas vezes é necessário registrar o estado interno de
um objeto.
• Implementação de mecanismos de checkpoints e de
desfazer que permitem aos usuários retroceder de
operações ou recuperar-se de erros.
• Trata-se de um objeto que armazena uma “instância” do
estado interno de um objeto.
© LES/PUC-Rio
Aplicabilidade
• Usado quando o estado de um objeto deve ser salvo de
maneira que possa ser restaurado mais adiante.
• O uso de interface para o obtenção do estado de um objeto
expõe detalhes da implementação que rompe o princípio de
encapsulamento de OO.
© LES/PUC-Rio
Estrutura
© LES/PUC-Rio
Participantes
• Memento
– Armazena o estado interno do objeto;
– Protege contra acesso por objetos que não o originador.
• Originador
– Cria um memento contendo uma “instância” do estado interno
corrente;
– Usa o memento para restaurar o seu estado interno;
• Caretaker
– É responsável pela custódia do memento;
– Nunca opera ou examina os conteúdos de um memento.
© LES/PUC-Rio
Conseqüências
• Preservação das fronteiras de encapsulamento
– O padrão evita a exposição de informação que somente um
originador deveria administrar.
• Ele simplifica o originador
– Coloca a carga de administração do armazenamento fora do
Originador.
• O uso de mementos pode ser computacionalmente
caro
– Se o Originador tiver que copiar grandes quantidades de
informação para armazenar no memento. Ou se os clientes
criam e devolvem mementos para o Originador com freqüência.
© LES/PUC-Rio
Implementação
class Originator {
class Caretaker {
private String state;
private List savedStates = new ArrayList();
public void set(String state) {
this.state = state;
public void addMemento(Object m) {
}
savedStates.add(m);
public Object saveToMemento() { }
return new Memento(state);
public Object getMemento(int index) {
}
return savedStates.get(index);
public void restoreFromMemento(Object
m)
{
}
if (m instanceof
} Memento) {
Memento memento = (Memento)m;
state = memento.getSavedState();
}
}
private static class Memento {
private String state;
public Memento(String stateToSave) {
state = stateToSave;
}
public String getSavedState() {
return state;
}
}
}
© LES/PUC-Rio
Implementação
• Armazenando mudanças incrementais
– Quando mementos são criados e passados de volta para o seu
originador, em uma seqüência previsível, um Memento pode
salvar somente a mudança incremental do estado interno do
originador.
• Proteção dos dados
– É importante impor métodos de proteger os dados do
memento. Somente o originador pode modificar ou obter os
dados internos de um memento.
© LES/PUC-Rio
Exemplo
• Controle de alterações de registros importantes
– Utilizando o padrão Memento, é possível guardar versões de
registros importantes a cada modificação.
– Para cada usuário que modificar o registro, podemos
armazenar em uma espécie de log o memento do registro e o
usuário que o alterou. Assim é possível ter uma auditoria,
verificando todas alterações feitas pelos usuários e permitindo
“voltar atrás”.
© LES/PUC-Rio
Download

Slides - (LES) da PUC-Rio