PATRONESMemento
PATRONES
MEMENTO
Frecuentemente los desarrolladores necesitan guardar el estado de un objeto para recuperarlo más tarde. Esto claro, sin perder el encapsulamiento del objeto.
Una de las maneras de hacerlo, es utilizando el patrón de diseño MementoMemento. En esta presentación vamos a ver como funciona, y un ejemplo práctico.
PATRONES
MEMENTO
Propósito
El objetivo principal de Memento es guardar el estado de un objeto sin romper el encapsulamiento del mismo.
PATRONES
MEMENTO
Donde Usar
• Se usa este patrón cuando se quiere poder restaurar el sistema desde estados pasados
• Es usado cuando se desea facilitar el hacer y deshacer de determinadas operaciones,
PATRONES
MEMENTO
UML
Originator
+state
+SetMemento()+CreateMemento()
Memento
+state
+GetState()+SetState()
Caretaker
return new Memento(state) state = m->GetState
PATRONES
MEMENTO
Participantes
Originator (ConstraintSolver)
• Crea el Memento y lo utiliza para recuperar su estado
• Esta es la clase del objeto en cuestión, es decir, del objeto a guardar/restaurar.
• Tiene dos métodos (uno para crear un objeto Memento a partir de su estado actual y otro para restablecer su estado actual a partir de un objeto Memento
PATRONES
MEMENTO
Memento (SolverState)
• Clase interna estática de Originator que contiene su estado. El Originator determina que datos almacenar en el Memento y solo el Originator debe ser capaz de leer el Memento
Caretaker (Undo mechanism)
• Es la clase que maneja los Mementos
• Nunca necesita saber que hay en Memento, solo necesita saber que el objeto que recibe permite restaurar el estado del Originator
PATRONES
MEMENTO
UML, (Interacción)
aCaretaker anOriginator aMemento
1 : CreateMemento()2 : SetState()
3 : SetMemento()4 : GetState()
MEMENTO
PATRONES
Ventajas y usos
• Deja alguna información en un objeto para que sea accesible por otro objeto utilizando control de acceso por defecto
•El Originator es más simple. En otros patrones que conservan la encapsulacion el Originator es el que tiene que registrar todos los estados distintos, es mucho más sencillo dar esa responsabilidad a la parte solicitante.
• Usar este patrón en operaciones de UNDO/REDO
• Se usa en transacciones de Bases de Datos
PATRONES
MEMENTO
Desventajas.
• Los mementos son costosos, es costoso crear los objetos Memento si se tiene que almacenar todas las partes del estado del Originator.
• El almacenamiento de los Memento es costoso, el cliente que desea guardar su estado, no conoce el tamaño real del Memento. Si su tamaño no se mantiene tan pequeño como sea posible CareTaker pagará el precio
MEMENTO
PATRONES
Patrones relacionados
• Command : el patrón Command utiliza Mementos para registrar el estado de las acciones que no se pueden hacer.
• State: la mayoría de los estados utilizan el patrón Memento
PATRONES
MEMENTO
Ejemplo
Un ejemplo donde se guarda temporalmente el estado de un perspectiva de venta, para después recuperarlo
La idea es tener una clase PersVenta que seria la Originator, es decir la que crea y usa el Memento
Una clase MemoriaPerspectiva que seria la CareTaker, es decir el responsable de la custodia del Memento
Una clase Memento, que como dice el nombre es el Memento
PATRONES
MEMENTO
public class PersVenta{
private String nombre, telefono; private double presupuesto; public void setNombre(String nombre){ System.out.println("Nombre "+ nombre); this.nombre = nombre; } public void setTelefono(String telefono){ System.out.println("Telefono: "+ telefono); this.telefono = telefono; } public void setPresupuesto(double presupuesto){ System.out.println("Presupuesto: "+ presupuesto); this.presupuesto = presupuesto; }
Clase OriginatorPropiedades del estado con métodos set
. . . .
public String getNombre(){ return nombre; } public String getTelefono() {return telefono;} public Double getPresupuesto() {return presupuesto;}
public Memento SalvaMemento(){ System.out.println("\nSalvando estado --\n"); return new Memento(nombre,telefono,presupuesto); }
public void RestauraMemento(Memento memento){ System.out.println("\nRestaurando estado --\n"); this.setNombre(memento.getNombre()); this.setTelefono(memento.getTelefono()); this.setPresupuesto(memento.getPresupuesto()); }}
Propiedades del estado con métodos get
Crea el Memento
Restaura el Memento
MEMENTO
PATRONES
PATRONES
MEMENTO
Clase Memento que guarda el estado del Objeto
public class Memento{ private String nombre; private String telefono; private double presupuesto;
public Memento(String nombre, String telefono, double presupuesto){ this.nombre = nombre; this.telefono = telefono; this.presupuesto = presupuesto; }
Mismas propiedades del Objeto a guardar
Constructor de la Clase
PATRONES
MEMENTO
. . . .
public void setNombre(String nombre){ this.nombre = nombre; }public void setTelefono(String telefono){ this.telefono = telefono; }public void setPresupuesto(double presupuesto){ this.presupuesto = presupuesto; } public String getNombre(){return nombre; } public String getTelefono() {return telefono;} public Double getPresupuesto() {return presupuesto;}}
Métodos set() y get() del Memento
PATRONES
MEMENTO
public class MemoriaPerspectiva{
private Memento memento; public void setMemento(Memento memento){ this.memento = memento; }
public Memento getMemento(){ return memento;}
}
Clase Caretaker, es la que cuida el Memento
PATRONES
MEMENTO
public class MainApp{ public static void main(String[] args){
PersVenta pv = new PersVenta(); pv.setNombre("Camilo"); pv.setTelefono("316 7985"); pv.setPresupuesto(15000); MemoriaPerspectiva m = new MemoriaPerspectiva(); m.setMemento(pv.SalvaMemento()); pv.setNombre("Andres"); pv.setTelefono("314 5485"); pv.setPresupuesto(18000);
pv.RestauraMemento(m.getMemento()); }}
Para finalizar la Clase donde está el Main()
Crea un Objeto de perspectiva de venta y le introduce propiedades
Guarda el estado
Vuelve y cambia el Originador
Restaura el estado guardado
PATRONES
MEMENTO
La salida del programa anterior sería:
Top Related