Patrones de diseño: Memento
Y después de unos días de vacaciones, vamos poco a poco retomando el ritmo de nuevo de la web, esta vez seguimos con los patrones de comportamiento, el patrón 'Memento'.
El patrón Memento te permite guardar y restaurar el estado previo de un objeto.
Supongamos que estamos en un juego y guardamos el estado del juego en el checkpoint 3, luego en el 5 y luego en el 6, si accedemos al estado cero, iremos al checkpoint 3, si accedemos al estado 1 al checkpoint 5 y así sucesivamente.
Se compone de 3 tipos de clases Originator, Memento y CareTaker.
El siguiente programa Java ilustra el uso de retroceder hacia atrás (el típico CTRL+Z), con el patrón Memento.
Intervienen tres clases:
- La clase Originator (Originador) es una clase que cambia de estado.
- La clase Caretaker (Portero) se encarga de registrar los cambios del Originador.
- La clase Memento (Recuerdo) guarda el objeto a salvaguardar
Clase Memento /** Este sería la clase que guarda nuestro estado, en este caso nuestro estado va a ser de tipo String **/
public class Memento {
private String state; // este atributo puede ser un objeto
public Memento(String state){
this.state = state;
}
public String getState(){
return state;
}
}
Clase Originator /** Esta clase se encarga de cambiar el estado, de almacenarlo de obtenerlo **/
/*********************************************************************/
public class Originator {
private String state;
public void setState(String state){
this.state = state;
}
public String getState(){
return state;
}
public Memento saveStateToMemento(){
return new Memento(state);
}
public void getStateFromMemento(Memento memento){
state = memento.getState();
}
}
Clase CareTaker /** Esta clase almacena el histórico de cambios, así podremos movernos por los distintos estados y momentos que hemos guardado, para ello usa un ArrayList de Memento, que es el objeto que guardaba nuestro estado **/
/*********************************************************************/
public class CareTaker {
private List<Memento> mementoList = new ArrayList<Memento>();
public void add(Memento state){
mementoList.add(state);
}
public Memento get(int index){
return mementoList.get(index);
}
}
Aqui tenemos un ejemplo de como sería la ejecución de todo, creamos una clase Originator, otra CareTaker, y vamos sobreescribiendo estados y alamcenando, como veis desde aquí no hacemos referencia directa a Memento, sino que se hace internamente **/
/*********************************************************************/
public class MementoPatternDemo {
public static void main(String[] args) {
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
originator.setState("State #1"); // Seteamos el estado
originator.setState("State #2"); // Sobreescribimos el estado
careTaker.add(originator.saveStateToMemento()); // Aquí se guarda solo el segundo estado
originator.setState("State #3");
careTaker.add(originator.saveStateToMemento());
originator.setState("State #4");
System.out.println("Current State: " + originator.getState());
originator.getStateFromMemento(careTaker.get(0));
System.out.println("First saved State: " + originator.getState());
originator.getStateFromMemento(careTaker.get(1));
System.out.println("Second saved State: " + originator.getState());
}
}
Como vemos, la ejecución de esto daría como resultado:
Current State: State #4
First saved State: State #2
Second saved State: State #3
Espero que te haya gustado la explicación y hayas entendido la introducción a este patrón de diseño, de nombre tan curioso.
No olvides seguirme en Twitter para más @juanmaperez_ nos vemos en la próxima :)