stringtranslate.com

Patrón de recuerdo

El patrón memento es un patrón de diseño de software que expone el estado interno privado de un objeto. Un ejemplo de cómo se puede utilizar esto es para restaurar un objeto a su estado anterior (deshacer mediante reversión), otro es el control de versiones, otro es la serialización personalizada.

El patrón memento se implementa con tres objetos: el originador , un cuidador y un memento . El originador es un objeto que tiene un estado interno. El cuidador va a hacer algo con el originador, pero quiere poder deshacer el cambio. El cuidador primero le pide al originador un objeto memento. Luego realiza la operación (o secuencia de operaciones) que iba a realizar. Para volver al estado anterior a las operaciones, devuelve el objeto memento al originador. El objeto memento en sí es un objeto opaco (uno que el cuidador no puede, o no debe, cambiar). Al usar este patrón, se debe tener cuidado si el originador puede cambiar otros objetos o recursos: el patrón memento opera en un solo objeto.

Los ejemplos clásicos del patrón memento incluyen un generador de números pseudoaleatorios (cada consumidor del PRNG actúa como un cuidador que puede inicializar el PRNG (el originador) con la misma semilla (el memento) para producir una secuencia idéntica de números pseudoaleatorios) y el estado en una máquina de estados finitos.

Estructura

Diagrama de clases y secuencias UML

Un ejemplo de diagrama de clase y secuencia UML para el patrón de diseño Memento. [1]

En el diagrama de clases UML anterior, la Caretakerclase hace referencia a la Originatorclase para guardar ( createMemento()) y restaurar ( restore(memento)) el estado interno del originador.
La Originatorclase implementa
(1) createMemento()creando y devolviendo un Mementoobjeto que almacena el estado interno actual del originador y
(2) restore(memento)restaurando el estado del Mementoobjeto pasado.

El diagrama de secuencia UML muestra las interacciones en tiempo de ejecución:
(1) Guardar el estado interno del originador: El Caretakerobjeto llama createMemento()al Originatorobjeto, que crea un Mementoobjeto, guarda su estado interno actual ( setState()) y devuelve el Mementoal Caretaker.
(2) Restaurar el estado interno del originador: El Caretakerllama restore(memento)al Originatorobjeto y especifica el Mementoobjeto que almacena el estado que se debe restaurar. El Originatorobtiene el estado ( getState()) del Mementopara establecer su propio estado.

Ejemplo de Java

El siguiente programa Java ilustra el uso "deshacer" del patrón memento.

import java.util.List ; import java.util.ArrayList ; class Originator { private String state ; // La clase también podría contener datos adicionales que no son parte del // estado guardado en el memento.. public void set ( String state ) { this . state = state ; System . out . println ( "Originador: Estableciendo el estado en " + state ); } public Memento saveToMemento () { System . out . println ( "Originador: Guardando en Memento." ); return new Memento ( this . state ); } public void restoreFromMemento ( Memento memento ) { this . state = memento . getSavedState (); System . out . println ( "Originador: Estado después de restaurar desde Memento: " + state ); } public static class Memento { private final String state ;                                                        public Memento ( String stateToSave ) { state = stateToSave ; } // accesible solo por la clase externa private String getSavedState ( ) { return state ; } } } class Caretaker { public static void main ( String [ ] args ) { List < Originator.Memento > saveStates = new ArrayList < Originator.Memento > (); Originator originator = new Originator ( ) ; originator.set ( " State1" ); originator.set ( " State2" ) ; saveStates.add ( originator.saveToMemento ( ) ) ; originator.set ( " State3 " ); // Podemos solicitar múltiples mementos y elegir a cuál revertir . saveStates.add ( originator.saveToMemento ( ) ) ; originator.set ( " State4 " ) ; originator.restoreFromMemento ( saveStates.get ( 1 ) ) ; } }                                                

La salida es:

Originador: Establecimiento del estado en Estado1Originador: Establecimiento del estado en State2Originador: Guardar en Memento.Originador: Establecimiento del estado en State3Originador: Guardar en Memento.Originador: Establecimiento del estado en State4Originador: Estado tras la restauración de Memento: Estado3

En este ejemplo se utiliza una cadena como estado, que es un objeto inmutable en Java. En situaciones de la vida real, el estado casi siempre será un objeto mutable, en cuyo caso se debe realizar una copia del estado.

Cabe señalar que la implementación mostrada tiene un inconveniente: declara una clase interna. Sería mejor si esta estrategia de memento pudiera aplicarse a más de un originador.

Existen principalmente otras tres formas de conseguir Memento:

  1. Publicación por entregas.
  2. Una clase declarada en el mismo paquete.
  3. También se puede acceder al objeto a través de un proxy, que puede realizar cualquier operación de guardar/restaurar el objeto.

Ejemplo de C#

El patrón memento permite capturar el estado interno de un objeto sin violar la encapsulación, de modo que más tarde se puedan deshacer o revertir los cambios si es necesario. Aquí se puede ver que el objeto memento se utiliza realmente para revertir los cambios realizados en el objeto.

clase Memento { cadena privada de solo lectura SavedState ;      Memento privado ( cadena estadoAGuardar ) { estadoGuardado = estadoAGuardar ; }        clase pública Originador { cadena privada estado ; // La clase también podría contener datos adicionales que no son parte del estado guardado en el memento.         public void Set ( string state ) { Console.WriteLine ( " Originador : Establecer el estado en " + state ) ; this.state = state ; }            public Memento SaveToMemento () { Console.WriteLine ( " Originador : Guardando en Memento." ); return new Memento ( state ) ; }         public void RestoreFromMemento ( Memento memento ) { state = memento.savedState ; Console.WriteLine ( " Originador : Estado después de restaurar desde Memento: " + state ) ; } } }            clase Caretaker { static void Main ( string [] args ) { var saveStates = new List < Memento > ();            var originator = new Memento . Originator (); originator . Set ( "State1" ); originator . Set ( "State2" ); saveStates . Add ( originator . SaveToMemento ()); originator . Set ( "State3" ); // Podemos solicitar múltiples mementos y elegir a cuál revertir. saveStates . Add ( originator . SaveToMemento ()); originator . Set ( "State4" );            originador . RestoreFromMemento ( saveStates [ 1 ]); } } 

Ejemplo de Python

""" Ejemplo de patrón Memento. """Clase  Originador :  _state  =  "" def  set ( self ,  state :  str )  ->  None :  print ( f "Originador : Estableciendo el estado en { state } " )  self._state = state   def  save_to_memento ( self )  -  > " Memento " :  devuelve  self.Memento ( self._state ) def  restore_from_memento ( self ,  m :  "Memento" ) -  >  None :  self._state = m.get_saved_state ( ) print ( f " Originador : Estado después de restaurar desde Memento: { self._state } " )    Clase  Memento : def  __init__ ( self ,  estado ):  self . _state  =  estado def  get_saved_state ( self )  : devuelve  self._stateestados_guardados  =  [] originador  =  Originador () originador . set ( "Estado1" ) originador . set ( "Estado2" ) estados_guardados . append ( originador . save_to_memento ())originador . set ( "State3" ) estados_guardados . append ( originador . save_to_memento ())originador . conjunto ( "State4" )originador .restaurar_desde_memento ( estados_guardados [ 1 ] )

Ejemplo de Javascript

// El patrón Memento se utiliza para guardar y restaurar el estado de un objeto. // Un recuerdo es una instantánea del estado de un objeto. var Memento = { // Espacio de nombres: Memento storedState : null , // El estado guardado del objeto.        guardar : función ( estado ) { // Guardar el estado de un objeto. this . saveState = estado ; },         restaurar : función () { // Restaurar el estado de un objeto. return this.savedState ; } } ;       // El Originador es el objeto que crea el memento. // define un método para guardar el estado dentro de un memento. var Originator = { // Espacio de nombres: Originator state : null , // El estado que se almacenará        // Crea un nuevo originador con un estado inicial nulo createMemento : function () { return { state : this . state // El estado se copia al memento. }; }, setMemento : function ( memento ) { // Establece el estado del originador a partir de un memento this . state = memento . state ; } };                       // El cuidador almacena los recuerdos de los objetos y // proporciona operaciones para recuperarlos. var Caretaker = { // Espacio de nombres: Caretaker mementos : [], // Los recuerdos de los objetos. addMemento : function ( memento ) { // Agrega un recuerdo a la colección. this . mementos . push ( memento ); }, getMemento : function ( index ) { // Obtiene un recuerdo de la colección. return this . mementos [ index ]; } };                       var action_step = "Foo" ; // La acción a ejecutar/el estado del objeto a almacenar. var action_step_2 = "Bar" ; // La acción a ejecutar/el estado del objeto a almacenar.        // establece el estado inicial Originator . state = action_step ; Caretaker . addMemento ( Originator . createMemento ()); // guarda el estado en el historial console . log ( "Estado inicial: " + Originator . state ); // Foo     // cambiar el estado Originator . state = action_step_2 ; Caretaker . addMemento ( Originator . createMemento ()); // guardar el estado en el historial console . log ( "Estado después del cambio: " + Originator . state ); // Barra      // restaurar el primer estado - deshacer Originator . setMemento ( Caretaker . getMemento ( 0 )); console . log ( "Estado después de deshacer: " + Originator . state ); // Foo   // restaurar el segundo estado - rehacer Originator . setMemento ( Caretaker . getMemento ( 1 )); console . log ( "Estado después de rehacer: " + Originator . state ); // Barra   

Referencias

  1. ^ "El patrón de diseño Memento: estructura y colaboración". w3sDesign.com . Consultado el 12 de agosto de 2017 .

Enlaces externos