universidad nacional de quilmes objetos puros observables y

Anuncio
U NIVERSIDAD N ACIONAL DE Q UILMES
T ECNICATURA EN P ROGRAMACI ÓN I NFORM ÁTICA
T RABAJO DE INSERCI ÓN PROFESIONAL
O BJETOS PUROS OBSERVABLES Y
TRANSACCIONALES
Alumno
Ronny De Jesús
[email protected]
Director
Co-Director
Ing. Nicolás Passerini Ing. Javier Fernandes
[email protected]
Noviembre 2012
[email protected]
INDICE
1
Indice
1. Introducción
3
2. Contexto
2.1. Construcción de interfaces de usuario usando el patrón MVC .
2.1.1. MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.2. Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.3. Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.4. Framework Arena . . . . . . . . . . . . . . . . . . . . . .
2.2. Transacciones . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3. Programación orientada a Aspectos . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
5
5
5
6
7
7
8
3. Estado del arte
3.1. Estrategias para la comunicación dominio-vista
3.1.1. Binding con eventos manuales . . . . . .
3.1.2. Formularios . . . . . . . . . . . . . . . . .
3.2. Manejo de transacciones en la UI . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
9
9
10
11
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4. Objetivo
12
5. Solución propuesta
5.1. Aspecto Observable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2. Aspecto Transaccional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3. Integración de ambos aspectos entre sı́ y con la UI . . . . . . . . . . . . . .
12
12
12
13
6. Nuestra herramienta:
6.1. Selección de un framework de aspectos .
6.2. Desarrollo de Aspect for Pure Objects .
6.3. Pure Object Transaction . . . . . . . . .
6.4. Pure Observable Objects . . . . . . . . .
6.5. Integración de POT, POO y Arena . . . .
6.6. Otras mejoras al Arena . . . . . . . . . .
13
14
14
16
17
17
19
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7. Aplicación de ejemplo
20
8. Conclusiones
22
9. Trabajo futuro
23
A. Modelo transaccional
24
B. Configuración e instalación
24
ÍNDICE DE FIGURAS
2
Índice de figuras
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Esquema MVC . . . . . . . . . . . . . . . . . . . . . . . . . .
Esquema de eventos definido por el estándar de Javabeans
Diagrama UML de la herramienta APO . . . . . . . . . . .
Fragmento de código del framework POO . . . . . . . . . .
Annotation para aplicar el aspecto transaccional. . . . . . .
Esquema de la herramienta POT . . . . . . . . . . . . . . .
Esquema de la herramienta POO . . . . . . . . . . . . . . .
Annotation para los aspectos Observable y Transaccional .
Ejemplo de binding anidado de la clase Transaction . . . .
Monitor de transacciones . . . . . . . . . . . . . . . . . . . .
Diagrama UML de la aplicación de ejemplo . . . . . . . . .
Pantalla de transferencia simple . . . . . . . . . . . . . . .
Fragmento de código de la Clase Transaction . . . . . . . .
Pantalla de múltiples transferencias . . . . . . . . . . . . .
Ejemplo del modelo transaccional . . . . . . . . . . . . . . .
Ejemplo del modelo transaccional anidado . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
10
15
16
17
18
19
19
19
20
21
21
21
22
24
25
1 Introducción
3
Resumen
Al desarrollar interfaces de usuario utilizando programación orientada a objetos,
con frecuencia gran parte del tiempo se destina a pocas tareas rutinarias, como el
traspaso de datos entre los objetos del dominio y los componentes de la interfaz gráfica. Si bien esta tarea es simple, cuando su realización es manual se vuelve propensa
a errores. Adicionalmente, muchas interfaces de usuario requieren que el usuario
tenga la posibilidad de cancelar la operación que está realizando. En una aplicación multiusuario, las tareas para garantizar consistencia ante una cancelación no
son sencillas. En este trabajo se propone una posible solución a estos problemas
basada en programación orientada a aspectos. Un primer aspecto permite que los
objetos de dominio disparen eventos en forma transparente al ser modificados, de
forma de actualizar la interfaz de usuario (UI) acorde a esos cambios. Un segundo aspecto automatiza las operatoria relacionada con las cancelaciones, permitiendo
que las modificaciones a los objetos del dominio se realicen siguiendo el concepto de
transacción, poniendo el foco en las propiedades de atomicidad, consistencia y aislamiento. La utilización de aspectos permite una solución automática y transparente
para estos problemas, que demuestra ser de gran utilidad en un amplio espectro de
aplicaciones.
1.
Introducción
En la construcción de aplicaciones de software, habitualmente se propone aislar las
tareas relacionadas con la interacción con el usuario y construir componentes especı́ficos que resuelvan esta problemática. De ésta manera, se diferencian en la aplicación
componentes que se ocupan de la interfaz de usuario (UI) y otros que modelan la lógica
del dominio. Esto se hace con el objetivo de minimizar el impacto de la UI sobre estos
últimos, para lograr una mayor flexibilidad y mantenibilidad del sistema.
Existen múltiples estrategias para resolver la comunicación entre los componentes
responsables de la UI y los que modelan la lógica del dominio, sin embargo muchas de estas estrategias se basan en tareas realizadas manualmente por parte del programador.
Si bien estas tareas son simples, requieren de grandes cantidades de código repetitivo
que suelen ser una fuente de errores e incrementan los costos del mantenimiento del
sistema.
Este trabajo tiene por objetivo automatizar dos tareas comunes en el desarrollo de
interfaces de usuario, focalizando en aplicaciones construidas siguiendo el paradigma
orientado a objetos.
La primera de estas tareas es el traspaso de datos entre los objetos del dominio y los
componentes de la vista, en el contexto de la creación de interfaces de usuario siguiendo
el patrón MVC.
La segunda tarea es proveer un mecanismo que permita deshacer cambios que se
hubieran realizado como parte de una operación que se comenzó y que no se puede o no
se desea finalizar. En el contexto de la programación orientada a objetos, estas operaciones son modificaciones en el estado de un objeto. Por ejemplo, si un usuario cancela
una operación desde la interfaz o si se produce una excepción durante la ejecución, la
aplicación debe garantizar que todos los objetos afectados se devuelvan al estado que
tenı́an antes de comenzar la operación inconclusa.
En este trabajo se propone una posible solución a estos problemas, basada en programación orientada a aspectos. Un primer aspecto, llamado Observable, permite que,
2 Contexto
4
en forma transparente, los objetos de dominio disparen eventos al ser modificados. De
esta forma la interfaz de usuario puede actualizarse y reflejar esos cambios en forma
automática.
Un segundo aspecto, llamado Transaccional, automatiza la cancelación de una operación, garantizando que todos los objetos quedan en el mismo estado en el que estaban
antes de comenzar. Esto permite que las modificaciones a los objetos del dominio se
realicen en forma transaccional, en particular respetando las propiedades de atomicidad, consistencia y aislamiento.
Para desarrollar los aspectos Observable y Transaccional, se construyó una herramienta llamada Aspects for Pure Objects (APO). APO es una herramienta que permite
crear aspectos fácilmente siguiendo los conceptos de la programación orientada a aspectos. APO fue creado para abstraer los conceptos fundamentales y complejos del framework Javassist [Chi00].
Para mostrar la posibilidad de componer los aspectos POO y POT se los integró en
una extensión del framework Arena. Arena es un framework educativo para la creación
de interfaces de usuario. Las extensiones desarrolladas en el marco de este trabajo han
sido incorporadas a la última versión del Arena que ya está siendo utilizada en la materia de Construcción de Interfaces de Usuario de la Universidad Nacional de Quilmes,
entre otras.
Este trabajo consta de las siguientes secciones:
Contexto
En la Sección 2 se introducen algunos de los conceptos básicos que son necesarios
para la compresión del trabajo.
Estado del Arte
En la Sección 3 se describen las estrategias más comunes utilizadas actualmente
en la industria para solucionar los problemas abordados en este trabajo.
Objetivo y Solución
La Sección 4 detalla el objetivo de este trabajo y la Sección 5 describe la estrategia
propuesta para alcanzarlo.
Implementación y Ejemplo
Las Secciones 6 y 7 describen la implementación de la herramienta y proveen ejemplos de utilización de la misma.
Conclusiones y Trabajo futuro
En las Secciones 8 y 9 se detallan las conclusiones del trabajo y y posibles caminos
para continuarlo.
Configuración e instalación
La Sección B provee las instrucciones necesarias para poder instalar y utilizar las
herramientas desarrolladas en este trabajo.
2.
Contexto
A continuación se describen los conceptos básicos preliminares para la comprensión
de este trabajo.
2.1
Construcción de interfaces de usuario usando el patrón MVC
2.1.
5
Construcción de interfaces de usuario usando el patrón MVC
2.1.1.
MVC
El patrón Modelo-Vista-Controlador (MVC) es una forma de construir interfaces de
usuario (UI) que propone dividir el comportamiento de una aplicación en tres partes
[Ree79]:
Modelo El modelo representa nuestra percepción del mundo real. Maneja el comportamiento y la información del dominio de la aplicación, responde a los pedidos
de información sobre su estado y tiene la responsabilidad última de llevar a cabo
el comportamiento del sistema.
Vista La vista tiene la responsabilidad de interactuar con el usuario. Es la parte
más fácil de identificar ya que es la que vemos en pantalla. La comunicación con el
usuario es bidireccional: por un lado muestra información proveniente del modelo
y por el otro lado recibe acciones de parte del usuario, que representa internamente
como eventos.
Controlador Es el intermediario entre el modelo y la vista. Captura los eventos
que produce cada uno de ellos y coordina la interacción entre los dos.
La idea principal de MVC, y que influyó a la mayorı́a de los frameworks de presentación posteriores, es la de Presentación Separada (Separated Presentation) [Bur87]. Esto
nos brinda una clara separación de responsabilidades entre interfaz, lógica de negocio y
control. Además nos permite soportar múltiples presentaciones para un mismo modelo
de información. La figura 1 muestra las relaciones entre los tres componentes.
Figura 1: Esquema MVC
2.1.2.
Eventos
Un evento es un suceso en el sistema, por ejemplo, una acción del usuario que requiere una reacción por parte del programa, o un cambio en el estado interno de un objeto
que podrı́a ser interesante para otros componentes. En un sistema orientado a eventos,
existen fuentes que producen eventos y listeners que se registran para ser notificados de
esos eventos y poder actuar en consecuencia.
2.1
Construcción de interfaces de usuario usando el patrón MVC
6
El patrón Observer es una forma común de implementar la idea de evento en lenguajes orientados a objetos. Gamma et al. [GHJV95] definen el patrón Observer de la
siguiente manera:
Objetivo Definir una dependencia 1:n de forma que cuando el objeto 1 cambie su estado, los n objetos sean notificados y se actualicen automáticamente, a estos objetos se los conoce como listener. Esto me permite una
comunicación entre objetos con muy bajo acoplamiento.
Motivación En la construcción de interfaces de usuarios, se tiende a separar los objetos de presentación (vistas) de los objetos de dominio, de
forma que se puedan tener varias vistas sincronizadas de la misma información.
2.1.3.
Binding
El binding es una conexión entre dos propiedades de dos objetos1 , que permite mantener sincronizado el valor de una propiedad en el primer objeto con el valor de alguna
propiedad en el segundo objeto. Habitualmente esto se logra a través del uso de eventos.
Una propiedad es una caracterı́stica que el objeto exhibe hacia su exterior, permite consultar su valor y en algunos casos también actualizarlo. Normalmente la implementación no será una variable de instancia, sino un mecanismo de más alto nivel que
dependerá de tecnologı́a que se este utilizando. Por ejemplo, en el lenguaje Java las propiedades siguiendo el contrato denominado JavaBeans, que especifica que un objeto que
tenga la propiedad nombre debe proveer implementaciones para los mensajes getNombre
y (opcionalmente) setNombre.
En la construcción de interfaces de usuario es habitual utilizar el concepto de binding
para sincronizar los datos que está viendo o modificando el usuario con la información
contenida en el modelo. Cada vez que el usuario ingresa o modifica un valor en la pantalla, la vista dispara un evento indicando el cambio de ese valor. Todas las propiedades
del modelo que estén conectadas con esa propiedad, serán actualizadas automáticamente. Esto permite que el modelo tome acciones en función de la información ingresada por
el usuario, por ejemplo validarla y rechazarla en caso de ser incorrecta. En caso que las
dos propiedades no sean del mismo tipo, el binding provee estrategias para realizar las
conversiones que fueran necesarias.
El binding provee una estrategia de muy alto nivel para comunicar información entre
los objetos de dominio y los componentes de la vista. En entornos sin binding, resolver
esta problemática suele requerir gran cantidad de trabajo, incrementando los tiempos
de desarrollo y la probabilidad de que ocurran errores en tareas repetitivas. Por ejemplo, es posible que mientras se está mostrando el valor de una propiedad en pantalla,
algún otro proceso en curso modifique el valor de esa propiedad; si no contamos con una
herramienta para automatizar la actualización de la información mostrada en pantalla,
la pantalla quedará desactualizada y mostrará al usuario información incorrecta.
Este trabajo se enfoca en bindings bidireccionales, es decir, aquellos que permiten
que el flujo de información vaya en ambos sentidos: si el modelo cambia se actualiza
1
Los términos binding y propiedad se utilizan con diferentes significados en otros contextos. En este
trabajo se consideran según su interpretación habitual en la construcción de interfaces de usuario.
2.2
Transacciones
7
la vista y si la vista cambia se actualiza el modelo. Para que esto sea posible tanto el
modelo como la vista deben disparar eventos cada vez que cambie el valor de alguna de
sus propiedades.
La necesidad de que los objetos de dominio disparen eventos plantea un problema
si (como en muchos casos) no tenemos soporte del lenguaje para eso. La implementación de eventos más habitual mediante un patrón Observer (2.1.2), implica agregarle
responsabilidades a los objetos de dominio que no tienen que ver con el dominio en sı́.
De esta manera, genera más burocracia, ensucia la interfaz y obliga a meter lógica para
disparar eventos, mezclado con la ejecución de la acción de negocio. En definitiva violar
el MVC por sı́ mismo no es algo malo, lo malo son las consecuencias que eso trae.
Otro problema que aparece frecuentemente es que el binding modifica los objetos
directamente, al menos en su versión más sencilla. Esto significa que cada vez que el
usuario ingresa un valor en la pantalla, se modifica el objeto de dominio asociado, aún
cuando la navegación de la aplicación podrı́a permitirle al usuario cancelar la operación
que está realizando. En caso de cancelarse la operación, los cambios realizados sobre los
objetos deben deshacerse para retrotraer el objeto al estado que tenı́a al comenzar la
operación. Implementar este proceso en forma manual es una tarea repetitiva y por lo
tanto propensa a que ocurran errores por parte del programador.
2.1.4.
Framework Arena
Arena es un framework para la construcción de interfaces de usuario. Esta creado
con fines educativos y por lo tanto se focaliza en la puesta en práctica de los principios de
diseño y organización de interfaces de usuario. El framework fue diseñado e implementado por el equipo docente de la materia de Construcción de Interfaces de Usuario de
la Tecnicatura Universitaria en Programación Informática de la Universidad Nacional
de Quilmes, en conjunto con docentes de la Universidad de San Martı́n y de la Facultad
Regional Buenos Aires de la Universidad Tecnológica Nacional.
2.2.
Transacciones
Una transacción es una unidad en la ejecución de un programa que se comporta
atómicamente: debe ejecutarse por completo o fallar sin hacer ninguna modificación, no
puede dejar los datos en un estado intermedio.
Los objetivos de trabajar con transacciones son dos. En primer lugar, la definición
de unidades de trabajo seguras, que permitan recuperarse de los errores y mantener la
coherencia de los datos, incluso en caso de fallas en el sistema. En segundo lugar, permitir el acceso concurrente, es decir, que múltiples usuarios utilicen la misma información
al mismo tiempo sin interferir entre sı́.
Para poder trabajar con transacciones se deben contar con instrucciones especiales
para marcar su inicio y su final:
Begin transaction es una operación que marca el inicio de una transacción.
Toda operación que se haga en adelante quedará en suspenso mientras
dure la transacción.
Commit es una operación que finaliza y confirma los cambios realizados desde el inicio de la transacción.
2.3
Programación orientada a Aspectos
8
Rollback es una operación que finaliza y revierte todos los cambios realizados desde el inicio de la transacción, dejando los datos en el estado que
tenı́an antes de comenzar.
Muchas veces las transacciones se asocian con los sistemas de gestión de bases de
datos, sin embargo es un concepto más general. Por ejemplo, en interfaces de usuario es
común incluir botones de “aceptar” y “cancelar” que podemos relacionar con las ideas de
commit y rollback. Si el usuario presiona el botón “cancelar” lo que se espera es que los
datos de la aplicación queden en el estado exacto en el que estaba antes de comenzar la
tarea.
Para garantizar la integridad de los datos, se considera que un sistema de transaccional debe cumplir con un conjunto de propiedades denominadas por el acrónimo ACID
[HR83]. De las propiedades ACID, este trabajo se concentra en las de Atomicidad, Consistencia y Aislamiento.
Atomicidad Una operación en un sistema de software se considera atómica cuando
se puede garantizar que no se realizará parcialmente aún cuando ocurran errores
durante su ejecución. En caso de operaciones complejas que constan de varias suboperaciones, si una de las sub-operaciones no se puede completar, ninguna de las
sub-operaciones debe ejecutarse. Si se detecta una falla después de que una de las
sub-operaciones ya fue realizada, se debe deshacer dicha sub-operación, garantizando que el sistema vuelva al estado original antes de comenzar la operación.
Consistencia Un sistema transaccional se considera que cumple con la propiedad de
consistencia si existe una forma de garantizar la integridad de los datos cada vez
que termina una transacción. En programación orientada a objetos, el encapsulamiento permite que cada objeto se ocupe de su propia consistencia. Entonces,
una estrategia para lograr consistencia es evitar que otras partes de la aplicación
manipulen los datos del dominio por fuera de los propios objetos de dominio.
Aislamiento Para cumplir la propiedad de aislamiento, ninguna transacción debe interferir con la ejecución de otra transacción. Es una práctica común considerar
diferentes niveles de aislamiento, que miden el grado de independencia que tienen
dos transacciones ejecutándose al mismo tiempo.
De los niveles de aislamiento habitualmente considerados [Ins92] en este trabajo
nos interesa alcanzar el nivel llamado Read commited.
2.3.
Programación orientada a Aspectos
La programación orientada a aspectos (AOP) es un paradigma de programación cuya intención es mejorar la modularización de las aplicaciones. En este paradigma se
considera que en una aplicación existen problemas que se deben solucionar que son ortogonales a la lógica del dominio [KLM+ 97]. Mientras que en otros paradigmas el código
necesario para solucionar estos problemas se disemina por la estructura de las unidades funcionales, el paradigma AOP provee herramientas para atacar estos problemas
sin modificar el código del dominio.
3 Estado del arte
9
Un aspecto es la unidad básica de construcción en AOP, debido a que permite modularizar los conceptos transversales (cross-cutting concerns) presentes en una aplicación.
Por ejemplo Logging, Profiling, entre otros. La definición de un aspecto se basa en los
conceptos de: Join Point, Point Cut y Advice.
Join Point Un Join Point puede ser definido como un punto de interés en
el código, como por ejemplo: la instanciación de una clase, el manejo de
una excepción, una llamada a un método, el retorno de un método, la
asignación a variable de instancia, etc.
Point Cut Un Point Cut es un predicado o condición que selecciona un conjunto de join points.
Advices Los Advices son las acciones que se ejecutan en cada Join Point
dentro de un mismo Point Cut, estas acciones se traducen en rutinas o
fragmentos de código.
3.
Estado del arte
El desarrollo de esta sección se enfoca en dos temas relacionados al presente trabajo:
la comunicación dominio-vista y el manejo de transacciones dentro de las interfaces de
usuario.
3.1.
Estrategias para la comunicación dominio-vista
La UI necesita obtener información del dominio para presentar al usuario, ası́ como
actualizar esa información a partir de las acciones del usuario. La necesidad de intercambiar información entre dominio e UI entra en conflicto con el objetivo de minimizar
el conocimiento entre ambas, como propone el patrón MVC.
Para solucionar esta contradicción la teorı́a MVC propone que la comunicación entre
dominio y vista se realice a través de eventos. Como se explicó en la Sección 2.1.2, los
eventos permiten formas de comunicación con un muy bajo acoplamiento. Sin embargo,
son pocos los lenguajes que incorporan un manejo automático de eventos, por eso se
requiere utilizar herramientas tecnológicas adicionales. A continuación detallaremos
las estrategias más utilizadas para abordar este problema.
3.1.1.
Binding con eventos manuales
En las tecnologı́as que no tienen manejo automático de eventos es necesario que los
objetos de dominio disparen eventos explı́citamente cada vez que cambia el valor de una
de sus propiedades.
Esta técnica es utilizada en frameworks como JFace-DataBinding2 y el Arena actual,
que se basan en el estándar de JavaBeans [SG00]. La figura 2 describe el esquema de
eventos utilizado en estas tecnologı́as. El framework lleva un registro de los listeners
interesados en cada propiedad de cada objeto, pero se obliga a cada objeto de dominio a:
Tener una referencia a un objeto que actúe como soporte para generar los eventos.
2
JFace-DataBinding es un Framework de presentación basado en el lenguaje Java y utilizado para la
construcción del entorno de trabajo Eclipse
3.1
Estrategias para la comunicación dominio-vista
10
Realizar una notificación cada vez que cambia una de sus propiedades.
Figura 2: Esquema de eventos definido por el estándar de Javabeans
La principal ventaja de esta estrategia es que permite una comunicación fluida y
desacoplada entre la vista y el modelo. El problema es que, para disparar los eventos
manualmente se necesita modificar las clases del dominio, agregando código que no se
corresponde con el objetivo principal de dichas clases. Además, implica escribir mucho
código repetitivo, que hace que sea muy fácil cometer errores.
3.1.2.
Formularios
En esta estrategia, durante la edición no se hace un binding de los datos contra el
modelo de dominio. En cambio, se almacenan en un lugar intermedio, dentro de la UI, y
no hay ninguna comunicación con el dominio hasta que el usuario no confirme la acción.
En ese momento se transfieren todos los datos juntos, en un único paquete.
Esta estrategia es la forma más tradicional de construcción de aplicaciones web.
El propio navegador de Internet es el que se ocupa de almacenar los datos durante la
edición de un formulario que luego se envı́a (submit) al servidor. Al recibir este pedido,
un componente dentro del servidor se ocupa de desarmar el paquete de datos que llega,
y transfiere esa información al dominio en forma manual.
Una vez procesado el pedido, el servidor contesta con una nueva página que el navegador debe presentar al usuario, reemplazando por completo la vista anterior. Durante
el armado de la página se va pidiendo al dominio cada dato que se desea mostrar. Dado
que se reemplaza por completo la pantalla del usuario, no hay necesidad de lanzar
eventos que permitan actualizar lo que el usuario estaba viendo.
En aplicaciones de escritorio sin binding se puede tener una estrategia similar. En lugar de tener un formulario que se envı́a como un paquete, los datos editados se guardan
en los propios controles de la UI. Cuando el usuario confirma la acción, manualmente se
toman los datos de los controles y se transfieren al dominio.
El problema de esta estrategia es que toda la comunicación debe ser realizada en
forma manual. Esto es tedioso de mantener y una posible fuente de errores. Además,
como almacenamos los datos fuera de los objetos de dominio, no podemos aprovechar
su lógica. Por ejemplo si el objeto de dominio tiene validaciones sobre sus atributos, no
las podemos aprovechar durante la edición. En aplicaciones web tradicionales, muchas
veces no se validan los datos hasta que no se intenta confirmar la operación, lo que
es bastante molesto para el usuario. En otros casos, para poder hacer validaciones a
3.2
Manejo de transacciones en la UI
11
medida que el usuario edita, la UI tiene su propia implementación de las validaciones.
Es decir, la lógica de validación está duplicada. Finalmente, estas técnicas no proveen
de ninguna estrategia para actualizar la vista en caso que el domino sea modificado por
otro proceso concurrente.
3.2.
Manejo de transacciones en la UI
Como se explicó en la sección 2.2, muchas veces las interfaces de usuario deben garantizar las propiedades ACID. Normalmente las tecnologı́as que se usan para construir
interfaces de usuario no tienen soporte nativo para manejar transacciones, entonces el
programador se ve obligado a implementarlas en forma manual.
Las estrategias más comunes apuntan principalmente a garantizar la atomicidad
de los cambios. Para ello se evita que la UI interactúe directamente con los objetos de
dominio. Si la acción que se está realizando desde la UI tuviera que modificar un atributo
objeto de dominio, el nuevo valor del atributo se almacena en algún “lugar intermedio”
hasta que se confirme toda la operación. Esta forma de trabajo simplifica el rollback:
simplemente se descarta la información intermedia. Los lugares de almacenamiento
intermedio pueden ser:
Un objeto desarrollado especı́ficamente a tal efecto, que sólo tiene los atributos
necesarios y ningún comportamiento [FRF+ 02, Sección Data Transfer Object].
Los propios componentes de la UI (por ejemplo una instancia de la clase TextBox).
En aplicaciones Web, el request cubre ese rol.
Una copia (clone) del objeto original.
En cualquiera de estas estrategias, en el momento de confirmar la operación se deberá “trasvasar” la información del almacenamiento intermedio a los objetos de dominio
involucrados. Con frecuencia esta operación es manual3 e implica una duplicación de conocimiento entre el objeto de dominio y el almacenamiento intermedio. Por ejemplo, en
caso de agregar un atributo al objeto de dominio se deberá garantizar que se mantiene
consistente con los almacenamientos intermedios.
Utilizar una copia del objeto original tiene algunas ventajas sobre las demás alternativas. En primer lugar se elimina la duplicación de conocimiento, al menos en parte.
Por otro lado, esta estrategia permite que la UI aproveche el comportamiento del propio
objeto durante la edición (por ejemplo: validaciones). Además, en esta estrategia hay
una variante que se utiliza para evitar el traspasamiento de datos, que es reemplazar el
objeto de dominio por la copia al final de la operación. Sin embargo, en sistemas complejos esta estrategia suele no ser suficiente, porque requiere que podamos conocer todas
las referencias al objeto que queremos reemplazar. Por otro lado, el reemplazo puede ser
muy complejo si la operación modifica múltiples objetos de dominio.
Como se observa, todas estas estrategias logran atomicidad a costa de duplicar información y agregar tareas manuales que pueden ser fuente de errores de programación.
En general no hay una forma sistemática de garantizar consistencia ni aislamiento.
3
En algunos casos puede automatizarse utilizando técnicas de reflection
4 Objetivo
4.
12
Objetivo
El primer objetivo de este trabajo es automatizar la comunicación entre el modelo y
la interfaz de usuario. Toda vez que el usuario ingrese información en el sistema, la información debe llegar directamente hasta el dominio. Esto nos permite aprovechar toda
la lógica del dominio durante la edición. De la misma forma, si cambia un atributo de
un objeto de dominio, se debe informar a la UI para que ese cambio sea visible inmediatamente. Toda esta funcionalidad debe poder ser implementada en forma transparente,
sin modificar el dominio ni imponerle restricciones.
El segundo objetivo es proveer un soporte para transacciones a nivel interfaz de
usuario, que permita automatizar el rollback en la operación en curso si no se puede
finalizar o si el usuario decide cancelarla. Además, dos usuarios deberán poder trabajar
con la misma información simultáneamente con un grado de aislamiento read committed.
5.
Solución propuesta
Basándonos en el paradigma AOP modelamos como aspectos dos conceptos: Observable y Transaccional. En las secciones subsiguientes se describe el comportamiento
de cada uno de estos dos aspectos y en la sección 5.3 la integración de ambos.
5.1.
Aspecto Observable
El aspecto Observable implementa un mecanismo transparente para que cuando un
objeto de dominio cambia, cualquier parte del sistema pueda recibir una notificación
informando ese cambio. Para ello, el sistema permite asociar a cada propiedad de un
objeto un conjunto de listeners. El aspecto intercepta modificación a una propiedad de
un objeto observado y notifica a los listeners que se han registrado para observar esa
propiedad.
Este mecanismo permite asociar acciones especı́ficas que se disparan cada vez que el
objeto es modificado. En particular, se utiliza para mantener sincronizada la UI con los
objetos del dominio.
5.2.
Aspecto Transaccional
El aspecto transaccional permite controlar la visibilidad de las modificaciones realizadas a un objeto. Llamamos objeto transaccional a los objetos a los que se les aplica
este aspecto.
Para controlar la visibilidad de las modificaciones realizadas sobre los objetos transaccionales, se define el concepto de contexto transaccional. Un contexto transaccional es un
espacio de trabajo en el cual se pueden realizar operaciones que no serán visibles fuera
de ese contexto. Toda acción realizada dentro del sistema es asociada con algún contexto
transaccional.
El aspecto transaccional intercepta en forma transparente todos los accesos al
estado interno de los objetos transaccionales, permitiendo la intervención del contexto.
Cuando se modifica el estado interno de un objeto transaccional el nuevo valor es almacenado en el contexto y el objeto permanece inalterado. Cuando se desea leer el estado
5.3
Integración de ambos aspectos entre sı́ y con la UI
13
interno de un objeto transaccional se toma el valor del contexto, en caso de existir. De
esta manera las operaciones realizadas dentro del mismo contexto ven un estado del
objeto que es distinto al que ven las operaciones realizadas en cualquier otro contexto.
Los contextos transaccionales se delimitan por las operaciones detalladas en la Sección 2.2 (beginTransaction, commit y rollback). La operación de commit confirma las
modificaciones y las hace públicas fuera del contexto. Por su parte, la operación de rollback provee un mecanismo automático para descartar todas las modificaciones realizadas dentro del contexto. Al ejecutarla, todos los objetos modificados dentro del contexto
regresan al estado que tenı́an al comenzar la transacción.
El contexto transaccional permite el trabajo concurrente, de esta forma varias operaciones dentro de un mismo sistema pueden acceder a un objeto transaccional al mismo
tiempo con un aislamiento de nivel read commited.
También se da soporte para transacciones anidadas, es decir, la posibilidad de abrir
un nuevo contexto transaccional dentro de otro contexto, denominado contexto padre.
Esta funcionalidad permite dividir una transacción en partes que pueden ser revertidas
o confirmadas individualmente.
La Sección A se muestra detalladamente como trabaja el aspecto transaccional.
5.3.
Integración de ambos aspectos entre sı́ y con la UI
Al utilizar los aspectos Observable y Transaccional simultáneamente aparecen situaciones complejas que deben ser tenidas en cuenta. También es necesario estudiar la
forma en que puedan integrar ambos aspectos con la UI. Para atacar estos problemas se
tomaron tres acciones:
1. Cuando la UI muestra en pantalla el valor de una propiedad de un objeto de dominio, debe registrarse como listener de esa propiedad. De esa forma, en caso de
producirse un cambio en el valor de la propiedad, la UI podrá reflejar esa modificación en forma inmediata.
2. Siempre que desde la UI el usuario tenga la posibilidad de cancelar una acción
que comenzó a realizar, se debe utilizar un contexto transaccional. Esto se logra
incluyendo en la UI las operaciones de beginTransaction, commit y rollback.
Consideramos que la decisión de cuándo comenzar o terminar una transacción no
puede ser decidida por nuestro framework de transacciones. La estrategia utilizada para integrar un framework especı́fico de UI con el aspecto transaccional es extender el framework elegido con herramientas que manejen los contextos transaccionales en forma automática.
3. La integración de los aspectos entre sı́ se logra asociando a cada listener con un
contexto transaccional y limitando el alcance de los eventos producidos por el aspecto observable para que sólo notifiquen a los listeners que se encuentran en la
mismo contexto transaccional que produjo el cambio.
6.
Nuestra herramienta:
En esta sección se explica como se llevó a cabo la implementación de la solución
propuesta en la Sección 5, cumpliendo a su vez los objetivos planteados en la Sección 4.
6.1
Selección de un framework de aspectos
14
Para ello se desarrollaron dos herramientas: Pure Objects Observable (POO) para atacar
a la problemática de la observabilidad, y Pure Object Transaction (POT) para atacar a
la problemática transaccional.
Todas las herramientas desarrolladas se encuentran publicadas bajo la licencia Creative Commons. En la sección B se encuentran las instrucciones para instalar la herramienta y links a la documentación disponible, junto con algunos ejemplos de uso.
6.1.
Selección de un framework de aspectos
Un primer paso para la implementación de la herramienta fue la selección de una
tecnologı́a que permitiera desarrollar utilizando AOP. Con ese objetivo, se evaluaron dos
frameworks: Javassist y AspectJ [KHH+ 01].
Encontramos que AspectJ es una herramienta de más alto nivel, que extiende el
lenguaje Java agregando construcciones especı́ficas para AOP. Sin embargo, AspectJ requiere que el programador que use nuestro framework utilice un compilador especı́fico,
provisto por AspectJ. Consideramos que esta caracterı́stica es negativa, por condicionar
el entorno de trabajo de los usuarios de nuestra herramienta.
Javassist, por su lado, aplica los aspectos al momento de la carga de las clases, sólo
requiere que utilicemos un ClassLoader especı́fico, resultando menos invasivo para los
programadores de aplicaciones basadas en nuestra herramienta. Como aspecto negativo, notamos que es un framework de muy bajo nivel que carece de las abstracciones
necesarias para modelar con aspectos y en cambio obliga a pensar a nivel de edición de
expresiones en el bytecode4 de una clase compilada.
Elegimos Javassist porque priorizamos minimizar el impacto hacia los usuarios de
nuestra herramienta. Para minimizar los problemas asociados a utilizar un framework
de tan bajo nivel, desarrollamos una herramienta que simplifica su uso, agregando algunas abstracciones útiles. Esta herramienta se describe en la sección siguiente.
6.2.
Desarrollo de Aspect for Pure Objects
El framework Javassist permite modificar directamente el bytecode de una clase en
el momento de cargarla. Por ser de tan bajo nivel es uno de los frameworks de aspectos
más poderosos, pero, por el mismo motivo, obliga a escribir código muy poco entendible.
Por eso se desarrolló una herramienta llamada Aspect for Pure Objects (APO), que permite definir aspectos utilizando conceptos de más alto nivel y aplicárselo a un grupo de
objetos.
La Figura 3 muestra esquemáticamente el diseño de la herramienta. Una instancia
de AdviceWeaver se ocupa de aplicar los cambios sobre las clases. Cada uno de los cambios que debe realizar el AdviceWeaver está modelado por un Advice, que consiste de
un PointCut y un conjunto de Interceptors.
El PointCut tiene la responsabilidad de determinar el conjunto de clases sobre el que
aplica el advice. Se provee algunas implementaciones básicas de point cuts, por ejemplo,
ClassPointCut, FieldPointCut, MethodPointCut, entre otros. Cada uno de estos point
cuts tienen un conjunto de funciones de filtro, definidas por el usuario programador que
use la herramienta.
4
El bytecode es un código de más bajo nivel que la maquina virtual de java ejecuta. El bytecode es
generado al momento de compilar la clase Java.
6.2
Desarrollo de Aspect for Pure Objects
15
Figura 3: Diagrama UML de la herramienta APO
Los Interceptors tienen la responsabilidad de realizar las modificaciones sobre los
join points de las clases seleccionadas por el point cut. Cada Interceptor intercepta
una acción especı́fica del código, por ejemplo llamadas a métodos, acceso a los atributos, etc. La herramienta provee algunas implementaciones de interceptors, por ejemplo,
FieldInterceptor, MethodInterceptor, etc. Cada Interceptor tiene un conjunto de
Behaviors. Los Behavior modelan cada modificación a realizar sobre los join points.
Estas modificaciones son modeladas como funciones por el programador. Existen varios
tipos de behavior, siguiendo la teorı́a de AOP: Before, After, Arround, ReadField y
WriteField.
Finalmente una instancia de APOClassLoader, instalada como class loader del sistema permite que antes de utilizar cualquier clase, ésta pueda ser procesada por el
AdviceWeaver.
Todas las modificaciones configuradas están expresadas en un lenguaje de alto nivel,
que luego el framework APO traduce al lenguaje de bajo nivel que requiere el framework
Javassist. La Figura 4 muestra un ejemplo de código de este lenguaje de alto nivel,
tomado del framework POO, que se describe en la Sección 6.4. A su vez, la Tabla 1
6.3
Pure Object Transaction
16
describe las expresiones más importantes de este lenguaje, su traducción al lenguaje de
expresiones de Javassist y su significado.
$Object oldValue = $oldValue;
$originalAsigment;
$this.firePropertyChange(’$fieldName’, oldValue, $newValue);
Figura 4: Fragmento de código del framework POO
Expr. APO
Expr. Javassist
Significado
$Object
java.lang.Object
El nombre completo de la clase Object
$this
$0
El objeto receptor del mensaje.
$newValue
$1
El primer parámetro del método.
$oldValue
$0.getAtribute()
El valor del atributo antes de la asignación que está siendo modificada.
$originalAsigment
$0.atribute = $1
La asignación del atributo con el primer
parámetro del método.
“$fieldName”
“atribute”
El nombre del atributo como un String.
Tabla 1: Tabla de equivalencia de expresiones. “atribute” es el nombre del atributo propiamente dicho.
APO es una herramienta abstracta, es decir, por sı́ sola no define ninguna modificación sobre las clases. En cambio, hay que configurarlo adecuadamente para obtener el
resultado deseado. POO y POT se construyeron siguiendo esta filosofı́a de creación de
aspectos.
6.3.
Pure Object Transaction
Pure Object Transaction (POT) es la herramienta que implementa el aspecto transaccional definido en la sección 5.2. Está basada en una implementación anterior de Nicolás
Passerini y Javier Fernandes, que se actualizó para aprovechar el framework APO y facilitar su integración con las demás herramientas desarrolladas.
Este framework intercepta todas las lecturas y escrituras de los atributos de un
objeto, delegando tanto las lecturas como las escrituras al administrador de las transacciones. A su vez, el administrador de transacciones asocia el pedido con un contexto
transaccional, que guarda los valores de los atributos de un objeto que fueron modificados durante la transacción en una estructura de la forma [objeto, [nombre del
atributo, valor]]. Cada contexto transaccional está asociado a un thread. Esto permite manejar la concurrencia en el acceso a la información de los objetos. Para aplicarle
este aspecto a una clase se utiliza la annotation Transactional como se muestra en la
Figura 5.
La herramienta provee también soporte para transacciones anidadas. Al momento
de hacer el commit en una transacción, los valores contenidos en el contexto transaccio-
6.4
Pure Observable Objects
17
@Transactional
public class Account {
}
Figura 5: Annotation para aplicar el aspecto transaccional.
nal son impactados en la transacción padre. En caso de tratarse de una transacción de
primer nivel, los cambios se impactan en los objetos de dominio usando reflection. Esta
forma de implementación permite que la identidad del objeto se mantenga, ya que el
objeto no se modifica ni se clona, sólo se intercepta el acceso a sus atributos.
Otro agregado a la versión original es la intersección de las modificaciones a un
objeto de tipo Collection, por ejemplo agregar o quitar objetos de una colección. Esto
presenta un desafı́o especial ya que habitualmente en los programas Java se utilizan las
implementaciones de colecciones provistas por el propio lenguaje y no es posible aplicar
aspectos sobre estas clases. En la nueva versión, este problema se resuelve reemplazando en forma automática las colecciones del lenguaje Java por implementaciones propias
de las mismas interfaces. La figura 6 muestra esquemáticamente el diseño de la herramienta.
6.4.
Pure Observable Objects
Pure Observable Objects (POO) es la herramienta que implementa el aspecto Observable planteado en la Sección 5.1. Los objetos cuyos atributos se desea poder observar
deben ser marcados con la Annotation Observable, como se muestra en la siguiente
fracción de código:
La implementación interna del aspecto agrega a las clases observables un atributo llamado changeSupport del tipo PropertySupport5 . Adicionalmente, se agregan
los métodos addPropertyChangeListener y removePropertyChangeListener que
permiten agregar y remover observadores respectivamente, y firePropertyChange
que notifica a los observadores que un atributo ha cambiado. La figura 7 muestra esquemáticamente el diseño de la herramienta.
6.5.
Integración de POT, POO y Arena
La integración entre Arena y POO se realizó construyendo una implementación de
PropertySupport que dispara los eventos de acuerdo a los esperados por el framework
Arena.
Por otro lado, la clase TransactionalDialog permite integrar Arena y POT, dado
que al definir una ventana como una subclase de TransactionalDialog, ésta se asocia automáticamente con un contexto transaccional. Al abrirse la ventana se efectúa la
operación de beginTransaction. Luego, botones Aceptar y Cancelar (que por defecto son
agregados por la superclase) efectúan las acciones de commit y rollback.
5
PropertySupport es una interfaz, la implementación concreta a utilizar se obtiene del archivo de
configuración.
6.5
Integración de POT, POO y Arena
18
Figura 6: Esquema de la herramienta POT
En tercer lugar, como se explicó en la sección 5.3, para integrar los dos aspectos entre
sı́ se requiere filtrar los eventos disparados por los objetos de dominio, limitándolos a las
ventanas que se encuentran dentro del mismo contexto transaccional. Se implementaron tres niveles de aislamiento de los eventos:
Fire all Todos los eventos disparados por el dominio son escuchados, sin importar si
están en un transacción.
Fire committed Sólo se escucha los eventos de las transacciones comiteadas
Fire only in my transaction sólo se escucha los eventos que ocurren dentro de su
transacción.
Finalmente, el framework se puede configurar para utilizar uno, otro o ambos aspectos, según se requiera. Los objetos pueden ser anotados con Observable y Transactional
como vimos previamente, o bien utilizar TransactionalAndObservable que es una unión
de ambas como se muestra en la Figura 8.
6.6
Otras mejoras al Arena
19
Figura 7: Esquema de la herramienta POO
@TransactionalAndObservable
public class Account{
}
Figura 8: Annotation para los aspectos Observable y Transaccional
6.6.
Otras mejoras al Arena
La integración se realizó con el lenguaje de programación Scala [OSV08]. Para llevar a cabo la integración fue necesario agregar las siguientes mejoras en el framework
Arena:
Bindings anidados Como se vio en la Sección 2.1.3, el binding es una conexión de
propiedades entre dos objetos. Con esta idea se desarrolló un tipo de binding que
permite conectar propiedades anidadas entre dos objetos.
La figura 9 muestra un ejemplo de binding anidado.
bindProperty("customer.address.street")
Figura 9: Ejemplo de binding anidado de la clase Transaction
Nuevos componentes Se agregaron estructuras visuales como árboles y listas.
Monitor de transacciones Se desarrolló un Monitor de Transacciones, que permite
debuggear las transacciones abiertas actualmente, mostrando los objetos afectados por la transacción y los atributos que se modificaron. La figura 10 muestra la
pantalla del monitor de transacciones.
7 Aplicación de ejemplo
20
Figura 10: Monitor de transacciones
7.
Aplicación de ejemplo
Para ilustrar el uso de las herramientas desarrolladas utilizaremos como ejemplo
una aplicación bancaria, en la que los clientes de un banco pueden transferir dinero de
sus cuentas a otras cuentas propias o de terceros. Realizar una transferencia implica
elegir dos cuentas, extraer el monto indicado de la primera y depositarlo en la segunda. En cualquiera de los dos pasos de la transferencia (extraer y depositar) se pueden
producir errores. Por ejemplo, el saldo puede ser insuficiente o el depósito puede superar el máximo permitido. La figura 11 muestra las clases que implementan la lógica del
dominio.
A continuación se describirán las dos pantallas más importantes de la aplicación, que
nos permitirán mostrar las diferentes utilidades brindadas por nuestra herramienta.
Pantalla de Transferencia Simple Esta primera pantalla permite elegir una de las
cuentas propias, otra cuenta de cualquier cliente del sistema y realizar una transferencia de la primera hacia la segunda con el monto indicado. Esta pantalla se
muestra en la figura 12.
Desarrollar esta utilidad con nuestra herramienta nos permite que el código sólo se
concentre en lo importante, que es debitar y extraer el monto. La figura 13 muestra
el método execute de la clase Transaction. Se puede ver que el código es limpio,
7 Aplicación de ejemplo
21
Figura 11: Diagrama UML de la aplicación de ejemplo
Figura 12: Pantalla de transferencia simple
no hay ningún comportamiento fuera de la lógica de negocio. Además, no es necesario ningún manejo de excepciones. En caso de producirse un error, la transacción
en forma automática va a producir el rollback de los cambios realizados.
public void execute(){
this.source.withdraw(this.amount);
this.destination.deposit(this.amount);
}
Figura 13: Fragmento de código de la Clase Transaction
Pantalla de Transferencias Múltiples Esta segunda pantalla nos permite realizar
múltiples transferencias simultáneamente. A diferencia de la transferencia simple, se agrega una lista con las transferencias que se llevan a cabo. Aquı́ se puede
8 Conclusiones
22
apreciar la utilidad de las transacciones anidadas, dado que las transferencias
pueden ser confirmadas o canceladas en su totalidad en cualquier momento. La
totalidad de las transacciones quedan firmes recién en el momento en el que se
acepta la operación principal. Esta pantalla se muestra en la figura 14.
Figura 14: Pantalla de múltiples transferencias
8.
Conclusiones
Hoy en dı́a existe gran cantidad de herramientas para el desarrollo de UI. Sin embargo algunos problemas que son muy habituales en los desarrollos industriales no son
resueltos adecuadamente por dichas herramientas. Cuando esto sucede, los programadores deben recurrir a soluciones ad-hoc, que muchas veces implican atacar problemas
generales de forma manual y escribiendo grandes cantidades de código rutinario, que
con frecuencia resulta propenso a errores.
En este trabajo abordamos dos problemas rutinarios de las UIs: por un lado la sincronización de datos entre la vista y el modelo de dominio; y por otro la posibilidad de
modelar operaciones que se realicen atómicamente.
Utilizando las ideas de la programación orientada a aspectos pudimos desarrollar
una herramienta que soluciona ambos problemas en forma transparente, dado que no
requiere que hagamos modificaciones en el código del dominio, y genérica, dado que es
aplicable a un gran conjunto de posibles dominios.
9 Trabajo futuro
23
Para poner a prueba el aspecto transaccional, se lo aplicó en una aplicación de mayor
tamaño que los ejemplos mostrados en este trabajo. Para eso se desarrolló la aplicación
de un kiosco, escrita en su totalidad en Scala y utilizando el framework Swing de Java
para la UI. Este desarrollo además nos permite comprobar que los aspectos están desacoplados entre sı́ y pueden ser utilizados independientemente del framework Arena.
Por otro lado, para dar soporte al desarrollo aprovechando el aspecto transaccional,
se desarrolló un sistema de monitoreo para las transacciones. Este sistema permite visualizar las transacciones, proveyendo una interfaz que muestra los objetos afectados
por la transacción.
Finalmente, los aspectos transaccional y observable fueron integrados al framework
Arena, favoreciendo su uso para la enseñanza de construcción de interfaces de usuario.
En las versiones previas los estudiantes tenı́an que disparar los eventos en forma manual, y eso implicaba explicar conceptos complejos, distrayendo la atención de los temas
fundamentales de la materia.
Como resultado adicional de este trabajo, se extendió el framework agregando nuevos componentes y ejemplos. A partir de estas modificaciones, el framework Arena está siendo utilizado no sólo en la Universidad Nacional de Quilmes, sino también en la Universidad Tecnológica Nacional (UTN) y en la Universidad Nacional de San Martı́n (UNSAM).
9.
Trabajo futuro
Estrategias de resolución de conflictos en las Transacciones Actualmente el aspecto transaccional no cuenta con una estrategia de resolución de conflictos en el
momento que dos o más transacciones confirman cambios sobre los mismos atributos de un objeto. Una estrategia posible es que se notifique al usuario que ese
objeto está siendo modificado por otra transacción. Otra estrategia podrı́a ser que
se bloquee el caso de uso cuando otra transacción esté manipulando alguno de los
objetos involucrados.
Niveles de Aislamiento en las Transacciones Actualmente sólo soporta el nivel de
aislamiento Read committed, serı́a conveniente implementar otros niveles de aislamiento 2.2.
Aplicación de aspecto observable en las Colecciones En la versión actual, los cambios realizados en las propiedades de los objetos como Arrays, Listas, Mapas, etc
no se les aplica el aspecto observable cuando se opera con ellos. Por ejemplo, las
operaciones de add o remove de una colección no producen eventos.
Integración de POO y POT independientemente del Arena Actualmente la integración de ambos aspectos se realizó utilizando conceptos implementados en Arena. Para llevar a cabo la integración se utilizó la clase TransactionalObservableValue que extiende de AbstractObservableValue. AbstractObservableValue es
una clase del framework que utiliza Arena para realizar el binding.
A Modelo transaccional
A.
24
Modelo transaccional
Para mostrar el funcionamiento del aspecto transaccional, utilizaremos como ejemplo un Producto. El producto tiene un stock y un state, que especifica si el producto
está habilitado o deshabilitado para la venta.
La Figura 15 muestra esquemáticamente como se ve el los contextos transaccionales
a medida que el objeto recibe mensajes de modificación y en la Figura 16 se muestra el
funcionamiento del modelo transaccional anidado.
(a) Se crean dos transacciones simultaneas
(b) Dentro del primer contexto se modifica el stock del producto, y ese cambio
no es visible para el segundo contexto.
(c) Dentro del segundo contexto se modifica el estado del producto, y ese cambio no es visible para el primer contexto.
(d) El primer contexto realiza un commit confirmando sus cambios e impactando los mismos en el objeto; el segundo contexto se entera de esa modificación.
Figura 15: Ejemplo del modelo transaccional
B.
Configuración e instalación
Todos los proyectos están disponibles en http://xp-dev.com/svn/uqbar/projects/.
Para más información sobre la configuración y armado del entorno de desarrollo https:
B Configuración e instalación
25
(a) Se crea una nueva transacción anidada a la
segunda.
(b) Los cambios mutuos no son visibles fuera de
su contexto.
(c) La transacción confirma sus cambios y estos
son impactados en la transacción padre
(d) La última transacción realiza
un commit, y todos los cambios con
impactados en el objeto.
Figura 16: Ejemplo del modelo transaccional anidado
//sites.google.com/site/programacionui/material/herramientas/arena y https:
//www.assembla.com/wiki/show/scala-ide/With_M2Eclipse.
REFERENCIAS
26
Referencias
[Bur87] Steve Burbeck. Applications programming in smalltalk-80(tm): How to use
model-view-controller (mvc), 1987.
[Chi00] Shigeru Chiba. Load-time structural reflection in Java, 2000.
[FRF+ 02] Martin Fowler, David Rice, Matthew Foemmel, Edward Hieatt, Robert
Mee, and Randy Stafford. Patterns of Enterprise Application Architecture.
Addison-Wesley Professional, 2002.
[GHJV95] E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns - Elements
of Reusable Object-Oriented Software. Addison-Wesley, 1995.
[HR83] T. Härder and A. Reuter. Principles of transaction-oriented database recovery. ACM Computing Surveys, 15(4):287–318, 1983. Description of ACID
transaction paradigm.
[Ins92] American National Standards Institute. American national standard for
information systems: database language — SQL: ANSI X3.135-1992. pubANSI, pub-ANSI:adr, 1992. Revision and consolidation of ANSI X3.135-1989
and ANSI X3.168-1989, Approved October 3, 1989.
[KHH+ 01] Gregor Kiczales, Erik Hilsdale, Jim Hugunin, Mik Kersten, Jeffrey Palm,
and William G. Griswold. Getting started with aspectj. Commun. ACM,
44(10):59–65, 2001.
[KLM+ 97] Gregor Kiczales, John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Videira Lopes, Jean-Marc Loingtier, and John Irwin. Aspect-oriented
programming. In ECOOP, pages 220–242, 1997.
[OSV08] Martin Odersky, Lex Spoon, and Bill Venners. Programming in Scala. Artima, Mountain View, CA, 2008.
[Ree79] Trygve Reenskaug. Models - views - controllers. Technical report, Technical
Note, Xerox Parc, 1979.
[SG00] João Pedro Sousa and David Garlan. Formal modeling of the enterprise
javabeans component integration framework. Technical Report CMU-CS00-162, Carnegie Mellon university, September 2000.
Descargar