Memento (informática) – Wikipédia, a enciclopédia livre

Memento é um padrão de projeto de software documentado no Catálogo Gang of Four, sendo considerado como um padrão comportamental. Ele permite armazenar o estado interno de um objeto em um determinando momento, para que seja possível retorná-lo a este estado, sem que isso cause problemas com o encapsulamento.[1]

Ele funciona de maneira que uma classe é responsável por salvar o estado do objeto desejado enquanto que uma outra classe fica responsável por armazenar todas essas copias (mementos).

O padrão Memento é implementado se utilizando de três elementos: Originador, Armazenador e o Memento.

O Padrão Comportamental Memento possui uma grande gama de aplicações onde é necessário a recuperação de um estado anterior de um objeto como um todo, qualquer tipo de editor precisa oferecer uma maneira de desfazer ações como restaurar imagens, textos etc. Para isso, o padrão Memento procura recuperar o estado anterior dessas ações e copiar os mesmos para um objeto a ser restaurado.

Participantes

[editar | editar código-fonte]

Três objetos estão envolvidos na implementação do padrão Memento.

  • Originador
    • é o objeto cujo estado se deseja capturar.
  • Memento
    • responsável por armazenar o estado interno do objeto Originador.
  • Armazenador
    • é o objeto que acessará o originador, e deseja desfazer qualquer mudança efetuada, caso necessário.
    • ele é responsável por armazenar todos os Mementos.
    • os Mementos devem ser recuperados de maneira LIFO (Last In First Out) onde o ultimo adicionado será o primeiro a ser recuperado.

O Armazenador deve requisitar um objeto memento, antes de se valer do originador. Após efetuar as operações desejadas no originador, o cliente devolve a este o objeto memento, caso deseje desfazer qualquer alteração.

O objeto memento não permite o acesso de qualquer classe além da classe originador. Assim, tal padrão mostra-se útil por não violar o conceito de encapsulamento.

Funcionamento

[editar | editar código-fonte]

O objeto representado na classe Originador cria um novo memento a partir de si próprio, é ele que vai controlar toda a execução do Padrão Memento, criando uma nova instância da classe Armazenador, sempre que haja alguma modificação derivada de ações do sistema e de seu funcionamento padrão, o Originador irá criar um novo Memento, externalizando seu estado interno para um novo objeto que se tornará o Memento que será armazenado para posterior restauração. Além dos métodos e atributos próprios do objeto a ser restaurado, o Originador conta com um atributo que represente o estado atual do mesmo, métodos para definir e atribuir o estado, e métodos para salvar e solicitar o estado a partir do Memento.

Com o estado salvo no Objeto Memento, o Originador volta suas atenções para o Armazenador, quando o método que aciona a ação de modificação é invocado, o Memento é criado e adicionado no Armazenador, que, a partir de agora guardará os Mementos em uma pilha, usando o LIFO, para tanto, o Armazenador possui uma lista do tipo do Memento, possui métodos para adicionar um novo Memento e para acessar o ultimo adicionado na pilha do Armazenador, quando o ultimo for retirado, o topo da lista será o Memento com o estado anterior ao que foi solicitado, e assim por diante, até que não haja mais Mementos para serem acessados, nesse momento deve ser lançada uma exceção.

O problema do Memento é que por ele sempre estar guardando o estado do objeto, ele pode guardar objetos demais e de maneira desnecessária e assim utilizando muito da memória da máquina.

Implementação

[editar | editar código-fonte]

O código em java a seguir ilustra a utilização do memento para desfazer ações de mudança de estado.

import java.util.List; import java.util.ArrayList; class Originator {     private String state; 
    public void setState(String state) {         System.out.println("Originator: Mudando estado para " + state);         this.state = state;     } 
    public Memento saveState() {         System.out.println("Originator: Salvando o Memento.");         return new Memento(this.state);     } 
    public void restoreState(Memento memento) {         this.state = memento.getSavedState();         System.out.println("Originator: Estado após restaurar o Memento: " + state);     } 
    public static class Memento {         private final String state; 
        public Memento(String stateToSave) {             this.state = stateToSave;         } 
        private String getSavedState() {             return this.state;         }     } } 
class Armazenador {     public static void main(String[] args) {         List<Originator.Memento> savedStates = new ArrayList<>(); 
        Originator originator = new Originator();         originator.setState("Estado1");         originator.setState("Estado2"); 
        savedStates.add(originador.saveState());         originator.setState("Estado3"); 
        // Podemos ter múltiplos mementos e escolher qual queremos restaurar.         savedStates.add(originator.saveState());         originator.set("Estado4"); 
        originador.restoreState(savedStates.get(1));     } } 

A saída deste código é:

Originador: Mudando estado para Estado1 Originador: Mudando estado para Estado2 Originador: Salvando o Memento. Originador: Mudando estado para Estado3 Originador: Salvando o Memento. Originador: Mudando estado para Estado4 Originador: Estado apos restaurar o Memento: Estado3 

Este exemplo utiliza uma String como o estado, o que é um objeto imutável em Java. Em cenários da vida real, o estado na maioria das vezes é um objeto, neste caso uma copia do objeto deve ser feita.

Ícone de esboço Este artigo sobre programação de computadores é um esboço. Você pode ajudar a Wikipédia expandindo-o.
  1. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. [S.l.]: Addison Wesley. pp. 283ff. ISBN 0-201-63361-2