Olá
pessoal, esse é o meu primeiro artigo para o iMasters e vou falar sobre um design pattern (padrão de projeto)
chamado Memento.
Você já conhece o Memento?
Segundo
o Wikipédia:
“Memento
é um padrão de projeto que permite armazenar o estado interno de um
objeto em um determinado momento, para que seja possível retorná-lo
a este estado, caso necessário.
Três objetos estão envolvidos na implementação
do padrão Memento.
- Originador é o objeto cujo estado se deseja capturar.
-
Memento é o objeto definido dentro da classe
Originador, com modificador de acesso privado, cujo estado do objeto
originador será armazenado. -
Cliente é o objeto que acessará o originador, e deseja
desfazer qualquer mudança efetuada, caso necessário.
O cliente 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.”
Para
ficar mais claro, vamos a um exemplo.
Suponhamos
que você possua um site que ofereça um serviço de customização
de carros. Onde o usuário poderá escolher a cor, jogo de rodas,
aerofólios e outros acessórios para o carro.
Imagine
ainda que cada vez que o usuário queira “salvar” determinada
configuração, você precise armazená-la para que sempre que as
alterações futuras forem desfeitas, você possa exibir o carro com
os atributos salvos anteriormente.
É
claro que existem diversas maneiras de fazer isso, mas aqui,
mostraremos como o Memento se comporta nesse tipo de situação.
Na
imagem abaixo temos um diagrama de estados que ilustra o nosso caso:

Explicando
nosso diagrama:
-
Temos
o nosso objeto em seu estado inicial. -
Depois
um método inicializa o objeto com suas devidas particularidades. -
Antes
de realizar a customização do carro é necessário verificar se
algum item foi escolhido. -
Caso
exista algum item escolhido, o objeto recebera esse item através do
método CustomizaCarro e então teremos o nosso objeto em seu novo
estado. -
Caso
não exista algum item escolhido, o objeto retorna seu estado
normal.
Bem,
é nesse momento que o Memento vai ajudar a gente a armazenar e
recuperar o objeto em seu estado de customização a qualquer momento
no seu sistema. Onde o estado pode ser o próprio carro configurado
ou alguma característica dele.
Traduzindo
isto para a linguagem Java, teremos:
1 import java.util.List;<br />1 import java.util.ArrayList;<br />2 class Originator {<br />private String state;<br />// A classe também pode conter outros dados que não fazem parte<br />// do estado guardado no Memento<br />public void set(String state) {<br />System.out.println("Originator: Setando o estado para: " + state);<br />this.state = state;<br />}<br />public Memento saveToMemento() {<br />System.out.println("Originator: Salvando no Memento.");<br />return new Memento(state);<br />}<br />public void restoreFromMemento(Memento memento) {<br />state = memento.getSavedState();<br />System.out.println("Originator: Estado após a restauração do Memento: " + state);<br />}<br />3 public static class Memento {<br />private final String state;<br />private Memento(String stateToSave) {<br />state = stateToSave;<br />}<br />private String getSavedState() {<br />return state;<br />}<br />}<br />}<br />4 class Caretaker {<br />public static void main(String[] args) {<br />List<Originator.Memento> savedStates = new ArrayList<Originator.Memento>();<br />Originator originator = new Originator();<br />originator.set("State1");<br />originator.set("State2");<br />savedStates.add(originator.saveToMemento());<br />originator.set("State3");<br />savedStates.add(originator.saveToMemento());<br />originator.set("State4");<br />originator.restoreFromMemento(savedStates.get(1));<br />}<br />}Explicando
o código acima, nós temos, em 1, dois
imports necessários para se trabalhar com List e ArrayList em Java.
Em 3, temos a nossa classe Memento, ela é
uma classe estática dentro do Originator que tem como função setar
ou recuperar determinado estado do objeto.
Em
2 temos o Originator, ele é o canal de
comunicação para com o Memento, é através dele que poderemos
armazenar e recuperar os estados via Memento.
Em
4 temos a classe Caretaker, note que foi
criado uma lista para salvar os estados do objeto. Depois setamos os
estados do Originator e ai chamamos os método savedStates.add
para armazenar os estados setados. Como a nossa lista é
indexada, podemos recuperar determinado estado a partir do método
originator.restoreFromMemento(savedStates.get(1)),
onde (1) é a posição do estado que se deseja recuperar.
O Memento é uma alternativa para sistemas onde os usuários fazem muitas
simulações e são necessários salvar ou desfazer essas
configurações em tempo de execução.
Mais
informações: http://sourcemaking.com/design_patterns/memento
Obrigado
a todos e até o próximo artigo.







