Patrones de Diseño en Bases de Datos Orientadas a Objetos – Parte III

Última parte de estos patrones.


Memento

 

El  patrón Memento, tiene como finalidad almacenar el estado de un objeto (o del sistema completo) en un momento dado de manera que se pueda restaurar en ese punto de manera sencilla. Para ello se mantiene almacenado el estado del objeto para un instante de tiempo en una clase independiente de aquella a la que pertenece el objeto (pero sin romper la encapsulación), de forma que ese recuerdo permita que el objeto sea modificado y pueda volver a su estado anterior.

 

Ejemplo de uso, motivación


 

Si estamos realizando una transacción en una base de datos y por alguna razón ocurre algún error y la transacción debe volver a ejecutarse, cualquier cambio de estado de los objetos persistentes serán deshechados por el motor de base de datos, es decir se haria un rollback, pero la consistencia de las Stacks o Heaps en las que están almacenados los objetos son responsabilidad de los programadores.

Así que si antes del inicio de una transacción, o hasta el punto de que una transacción anidada se inicia, los estados de las Heaps o Stacks se acumula, el programador debe asegurarse de que las transacciones que se deben volver a ejecutar, no dejen inconsistentes los estados de las Heaps o Stacks.

 

Utilización


 

Se podría tratar de volver atrás todos los estados, a las últimas transacciones exitosas o se puede registrar el estado interno de los objetos implicados. En este caso, se debe guardar la información de estado en algún lugar para que puedan restaurarse los objetos a su estado anterior.

Pero los objetos normalmente encapsulan parte o la totalidad de su estado, por lo que es inaccesible desde otros objetos e imposible de guardar externamente. La exposición de este estado violaría la encapsulación, y esto puede comprometer la fiabilidad de la aplicación y extensibilidad.

El patrón de comportamiento Transaction Memento, propone un modelo para capturar y externalizar el estado interno de un objeto para restaurarlo más tarde sin violar  el encapsulamiento.

Para lograr esto el patrón define 3 clases:

 

Originator:

  • Originator crea un objeto Memento conteniendo una fotografía de su estado interno.
  • Originator usa a Memento para restaurar su estado interno.

 

Caretaker: 

  • Es responsable por mantener a salvo a Memento.
  • No opera o examina el contenido de Memento

 

Memento:

  • almacena el estado interno de un objeto Originator. El Memento puede almacenar mucho o parte del estado interno de Originator.
  • Tiene dos interfaces. Una para Caretaker, que le permite manipular el Memento únicamente para pasarlo a otros objetos. La otra interfaz sirve para que Originator pueda almacenar/restaurar su estado interno, sólo Originator puede acceder a esta interfaz, al menos en teoría.

 

Colaboraciones


Aquí ‘caretaker’ pide un memento al objeto Transient, lo mantiene por un tiempo, y lo pasa de vuelta al originador cuando la transacción comienza, como lo ilustra el siguiente diagrama:

El nuevo objeto memento es creado y retenido de un lado por el objeto ‘care taker’ antes de que comience la transacción, y el método setMemento() es llamado como la primer llamada dentro de la transacción, por lo tanto si la transacción se reitera, la primer cosa que ocurre es que el estado del objeto Transient vuelve a su estado original.

  

Estructura del patrón


 

Aplicabilidad


 

El patrón Memento es aplicable cuando todo o parte del estado de un objeto debe ser guardado para ser estaurado más tarde o, una interfaz directa para obtener el estado de un objeto exponga detalles de su implementación.

Es usado en muchos ObjectStore para manejar las Heaps que mantienen a lso objetos durante las transacciones que necesitan hacer roll-back.

  

Consecuencias


 

Si Originator tendría que  almacenar y mantener a salvo una o muchas copias de su estado interno, sus responsabilidades crecerían y serían más complejas, se desviaría de su propósito disminuyendo la coherencia.

Usar Mementos hace que Originator sea mucho más sencillo y coherente.

El uso frecuente de Mementos para almacenar estados internos de gran tamaño, podría resultar costoso y perjudicar el rendimiento del sistema.

Caretaker al no conocer detalles del estado interno de Originator, no tiene idea de cuanto espacio y tiempo se necesita para almacenar el estado interno de Originator en un Memento y restaurar su estado interno a partir de un Memento. Por lo que no puede hacer predicciones de tiempo ni de espacio.

Memento debería proporcionar una interfaz privada, a la que sólo Originator puede acceder. Esta interfaz incluye la creación, el almacenamiento y recuperación del estado interno de Originator. Además una interfaz pública que permita la destrucción de Memento.

 

Ventajas de su uso


 

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 las partes solicitantes.

Usar este patrón en operaciones UNDO/REDO.

 

Conclusiones


 

Memento es una buena alternativa de diseño, para guardar el estado interno de un objeto preservando la encapsulación, aunque en la práctica no es posible preservar la encapsulación debido a que no es posible implementar en la mayoría de los lenguajes de programación orientados a objetos.

 

Ejemplo y Código


 

Un ejemplo donde se guarda temporalmente el estado de una 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:

 

Conclusión


 

Hemos visto cómo patrones de diseño simples y orientados a las bases de datos ayudan a resolver problemas frecuentes de acceso, modificación y de recuperación de errores relacionados con bases de datos orientadas a objetos.

Estas bases de datos orientadas a objetos permiten tratar directamente con objetos, no teniendo que hacer la traducción a tablas o registros. Sus objetos se conservan y pueden ser gestionados aunque su tamaño sea grande, pueden ser compartidos entre múltiples usuarios  y mantienen su integridad como sus relaciones. Para satisfacer todas estas características y mantener la persistencia y consistencia de los mismos, hemos visto como los patrones de diseño le permiten al programador un buen manejo de estos objetos, manteniendo las necesidades y caracterísitcas que deben cumplir las bases de datos.

Los objetos son integrados con facilidad con los lenguajes de programación que permiten la utilización de objetos y las BDOO, al estar todo en un solo paradigma los programadores se ven facilitados en varios aspectos, como la facilidad de pensar solo en un paradigma o la gran cantidad de objetos ya desarrollados por terceros o los patrones de diseño para problemas recurrentes, reusabilidad, etc.

Dejá un comentario