Está en la página 1de 24

Implementacin de Asociaciones UML en Java*

Gonzalo Gnova, Carlos Ruiz del Castillo, Juan Llorens


Departamento de Informtica, Universidad Carlos III de Madrid
Avda. Universidad 30, 28911 Legans (Madrid), Spain
{ggenova, llorens}@inf.uc3m.es, crcu@inicia.es

Resumen. Los lenguajes de programacin orientados a objetos no contienen ni la


sintaxis ni la semntica necesarias para expresar directamente las asociaciones. Por
tanto, hay que implementar las asociaciones UML mediante una adecuada
combinacin de clases, atributos y mtodos. Este artculo presenta algunos principios
para la implementacin de asociaciones binarias UML en Java, prestando especial
atencin a la multiplicidad, la navegabilidad y visibilidad. Nuestro anlisis ha
encontrado algunas paradojas en la especificacin de la visibilidad para las
asociaciones bidireccionales. Hemos utilizado estos principios para escribir una serie
de plantillas de cdigo que utilizamos en combinacin con una herramienta para
generar el cdigo de las asociaciones, que son ledas de un modelo almacenado en
formato XMI.

1. Introduccin
Uno de los bloques de construccin claves en el Lenguaje Unificado de Modelado
[UML] es el concepto de asociacin. Una asociacin (association) en UML se define
como un tipo de relacin (relationship) entre clases1, que representa la relacin semntica
entre dos o ms clases que implica conexiones o enlaces (links) entre sus instancias [UML,
p. 2-20]2.
Como ya ha sido denunciado hace tiempo [Rumbaugh 87], los lenguajes de
programacin orientados a objetos expresan bien la clasificacin y la generalizacin, pero
no contienen ni sintaxis ni semntica para expresar directamente las asociaciones. Por tanto,
hay que implementar las asociaciones mediante una adecuada combinacin de clases,
atributos y mtodos [Rumbaugh 96a, Noble 96, Noble 97, Ambler 01]. La idea ms simple
consiste en aadir un atributo que almacene los enlaces de la asociacin, y mtodos lectores
(accessors) y mutadores (mutators) para manipular los enlaces. Otras tcnicas hacen
hincapi en el uso de interfaces de Java para implementar las asociaciones, lo que presenta
algunas ventajas [Harrison 00].
Las herramientas CASE a menudo proporcionan algn tipo de generacin de cdigo a
partir de los modelos de diseo3, pero limitada a un esqueleto de cdigo que incluye slo

Publicado originalmente como Gonzalo Gnova, Carlos Ruiz del Castillo, Juan
Llorens. Mapping UML Associations into Java Code, Journal of Object Technology,
2(5): 135-162, Sep-Oct 2003.
1
En realidad clasificadores. Classifier es una superclase de Class en el metamodelo de
UML.
2
La actual propuesta de communityUML al OMG para el desarrollo de UML 2.0
[cUML] sugiere un cambio de terminologa: asociacin en lugar de enlace y tipo de
asociacin en lugar de asociacin. Si bien apoyamos este cambio, este artculo vamos a
seguir la actual terminologa oficial de UML.
3
Distinguimos aqu entre modelos de anlisis y modelos de diseo. Un modelo de
anlisis es una abstraccin del problema (el mundo real tal como es antes de que se
construya el sistema propuesto), mientras que un modelo de diseo es una abstraccin de la

2
generalizaciones y clases, con las signaturas de los atributos y los mtodos, pero sin
asociaciones4. El programador tiene que escribir manualmente el cdigo para gestionar las
asociaciones de modo controlado, de forma que se tengan en cuenta todas las restricciones e
invariantes para obtener una implementacin correcta. Habitualmente esto es una tarea
repetitiva que podra automatizarse hasta cierto punto. Adems, el nmero de aspectos que
el programador tiene que tener en cuenta al escribir el cdigo para las asociaciones es tan
grande, que se arriesga continuamente a olvidar algn detalle vital, especialmente cuando
se trata de asociaciones mltiples (con multiplicidad mayor que 1) o bidireccionales
(navegables en ambas direcciones). Ms an, el cdigo escrito finalmente se encuentra con
frecuencia disperso entre el cdigo de las clases participantes, hacindolo ms difcil de
mantener.
El objetivo de este trabajo es doble. En primer lugar, escribir una serie de plantillas de
cdigo que ayuden a los programadores a traducir las asociaciones UML al lenguaje
orientado a objetos destino. En este trabajo el lenguaje escogido es Java, aunque los
principios que hemos seguido son aplicables a otros lenguajes prximos como C++ o el
entorno .NET. En segundo lugar, construir una herramienta que usando estas plantillas
genere cdigo para las asociaciones, que sern ledas de un modelo almacenado en formato
XMI5. Un tercer objetivo ser posibilitar la ingeniera inversa, es decir, obtener las
asociaciones entre clases a partir del anlisis del cdigo que las implementa. Nuestra
herramienta no lleva a cabo actualmente esta tarea, aunque es muy sencilla y directa si el
cdigo ha sido escrito con nuestras plantillas. Una descripcin completa de las plantillas y
herramientas est fuera del alcance de este artculo, pero puede encontrarse en otros lugares
[Ruiz 02].
Las asociaciones en UML pueden tener una gran variedad de propiedades (features). El
presente trabajo se limita al anlisis e implementacin de las propiedades de multiplicidad,
navegabilidad y visibilidad en asociaciones binarias. Excluye, por tanto, algunos tipos ms
complejos de asociaciones como asociaciones reflexivas, asociaciones todo/parte
(agregaciones y composiciones), asociaciones cualificadas, clases-asociacin, y
asociaciones n-arias. Excluye tambin propiedades tales como ordenacin (ordering),
modificabilidad (changeability), etc.
Las tres Secciones siguientes de este artculo estn dedicadas al estudio de las
propiedades de multiplicidad, navegabilidad y visibilidad de las asociaciones, con un
anlisis detallado de los posibles problemas y soluciones propuestas. Luego, la Seccin 5
contiene la descripcin de una interfaz uniforme para todos los tipos de asociaciones desde
el punto de vista de las clases participantes, tal como son implementadas con nuestras
plantillas y herramientas. Finalmente, la Seccin 6 describe brevemente cmo funciona
nuestra herramienta.

2. El problema de la multiplicidad
La multiplicidad de una asociacin binaria, situada junto al extremo de la asociacin (el
extremo destino), especifica el nmero de instancias destino que pueden estar asociadas a
una nica instancia origen a travs de la asociacin en cuestin, en otras palabras, cuntos
objetos de una clase (la clase destino) pueden estar asociados con un nico objeto dado de
la otra clase (la clase origen) [RM, p. 348; UML, p. 2-23]6.
solucin (la construccin interna del sistema propuesto) [Kaindl 99], por tanto la
generacin de cdigo slo tiene sentido para los modelos de diseo.
4
Algunas herramientas son una excepcin a esta regla [Fujaba, Rhapsody].
5
XML Metadata Interchange [XMI], un formato basado en XML diseado para
almacenar e intercambiar modelos UML entre distintas herramientas.
6
Otras notaciones invierten la posicin de los valores de multiplicidad, siguiendo el
convenio extremo cercano en lugar del convenio extremo lejano, que es el usado en

3
El clsico ejemplo de la Figura 1 ilustra la multiplicidad binaria. Cada instancia de
Persona puede trabajar para cero o una instancias de Empresa (0..1), mientras que cada
empresa puede estar enlazada a una o ms personas (1..*). Para aquellos lectores menos
familiarizados con la notacin de UML, el smbolo (*) significa muchos (nmero
ilimitado), y los rangos (1..1) y (0..*) pueden abreviarse respectivamente como (1) y (*).

Persona

1..*

0..1
trabaja para

Empresa

Figura 1. Un clsico ejemplo de asociacin binaria con la expresin de multiplicidades

Las posibles multiplicidades en UML incluyen cualquier subconjunto de los enteros no


negativos [RM, p. 346], sin estar limitadas slo a un nico intervalo como (2..*), o a una
lista de intervalos enteros separados por comas como (1..3, 7..10, 15, 19..*): tambin son
vlidas las especificaciones de multiplicidad tales como {nmeros primos} o {cuadrados de
enteros positivos}, aunque no hay notacin estndar para ellas. No obstante, en UML, como
en otras tcnicas de modelado, las multiplicidades ms habituales son (0..1), (1..1), (0..*) y
(1..*). Nuestro anlisis quedar restringido a multiplicidades que puedan expresarse como
un nico intervalo entero en la forma (min..max).
La restriccin de multiplicidad es un tipo de invariante, es decir, una condicin que
debe ser satisfecha por el sistema. Una posible prctica al programar es no comprobar el
invariante en todo momento, sino slo cuando lo pida el programador, despus de
completar un conjunto de operaciones que se supone dejan el sistema en un estado vlido
(una transaccin). Esta prctica es ms eficiente en tiempo de ejecucin, y da al
programador ms libertad y responsabilidad en la escritura del cdigo, con el
correspondiente riesgo de que se olvide de incluir las necesarias comprobaciones y deje el
sistema por descuido en un estado errneo. Por otra parte, pensamos que comprobar las
restricciones de multiplicidad no es excesivamente ineficiente en consumo de tiempo,
especialmente cuando se compara con el tiempo requerido para gestionar colecciones o
sincronizar asociaciones bidireccionales (ver Seccin 3.2). As pues, pensamos que vale la
pena hacer todo lo que podamos para descargar al programador, de modo que nuestro
primer objetivo ser analizar la posibilidad de realizar comprobaciones automticas para las
restricciones de multiplicidad.
2.1. Asociaciones opcionales y obligatorias
El valor de la multiplicidad mnima puede ser cualquier entero positivo, aunque los
valores ms comunes son 0 y 1. Cuando el valor es 0 decimos que la asociacin es opcional
(optional) para la clase en el extremo opuesto (clase Persona en la Figura 1), y decimos
que es obligatoria (mandatory) cuando el valor es 1 o mayor (clase Empresa). Las
asociaciones opcionales no presentan problemas especiales para la implementacin, pero
las obligatorias s. Desde el punto de vista conceptual, un objeto que participa en una
asociacin obligatoria tiene que estar enlazado en todo momento con un objeto (o ms) al
otro lado de la asociacin, en caso contrario el sistema est en un estado errneo. En el
ejemplo de la Figura 1, una instancia de Empresa necesita siempre una instancia de
Persona. Por tanto, en el mismo momento en que se crea una instancia de Empresa hay
que enlazarla a una instancia de Persona.
UML. Est bien establecido que la semntica de ambas convenciones es equivalente para
asociaciones binarias, pero difiere sustancialmente cuando se aplican a asociaciones de
mayor grado [Song 95, McAllister 98, Castellani 00, Gnova 02, Gnova 03b].

4
Esto puede ocurrir de tres formas distintas:
 Una instancia de Empresa es creada por una instancia de Persona y enlazada a
su creador.
 Una instancia de Empresa es creada con una instancia de Persona suministrada
como parmetro.
 Una instancia de Empresa es creada y solicita la creacin de una instancia de
Persona.
El tercer caso plantea problemas adicionales. La creacin de una persona probablemente
requerir datos adicionales, como el nombre, la direccin, etc., y no parece muy razonable
suministrarlos en la creacin de una empresa. Este problema empeora si Persona tiene
otras asociaciones obligatorias, por ejemplo con el pas donde vive: si ste fuera el caso, la
creacin de una empresa requerira suministrar datos para crear una persona, un pas, etc.
La solucin ms obvia es permitir slo las dos primeras formas de instanciacin. Pero
supngase entonces que la asociacin es obligatoria en los dos extremos. Cul de las dos
instancias hay que crear primero? No tenemos una eleccin satisfactoria, ya que dejaramos
al sistema en un estado errneo hasta que las dos creaciones hayan terminado. Podemos
pensar en una creacin atmica de las dos instancias, pero esto vale slo para el caso ms
sencillo en el que slo hay dos clases implicadas. Tendremos que definir creaciones
atmicas para dos, tres, cualquier nmero de clases? En la destruccin de objetos surgen
problemas similares.
Imaginemos ahora que no vamos a crear o destruir instancias, sino que vamos a cambiar
enlaces entre instancias. Si queremos cambiar la instancia de Empresa que est enlazada
con una determinada instancia de Persona, podemos borrar simplemente el enlace con la
antigua empresa y aadir un nuevo enlace a la nueva empresa. Esto funciona siempre que la
antigua empresa est enlazada con otras instancias de Persona; incluso podemos borrar el
enlace y no aadir ninguno, ya que la asociacin es opcional para Persona. Si slo
tuviramos una persona enlazada a una empresa determinada, tendramos que suministrar
una nueva persona a la empresa antes de borrar el enlace con la antigua persona, pero esto
no es ms que el comportamiento especificado (la asociacin es obligatoria para
Empresa) y no podemos quejarnos por eso.
No obstante, aqu encontramos nuevos problemas. Si la asociacin con Empresa fuera
obligatoria tambin para Persona (es decir, multiplicidad 1..1 en lugar de la presente
0..1), la instancia de Persona no podra borrar el antiguo enlace con la empresa y luego
aadir el nuevo enlace, ni podra hacerlo en el orden inverso, primero aadir, luego
borrar, porque pasara por un estado errneo del sistema. Un cambio atmico de enlaces
sera vlido slo para los casos ms sencillos, pero no para casos ms complicados como el
siguiente, que es ms bien retorcido (ver Figura 2): consideremos las clases A y B,
asociadas con multiplicidad 1..1 en ambos extremos, y las correspondientes instancias a1,
a2, b1 y b2. En el estado inicial tenemos los enlaces a1-b1 y a2-b2. En el estado final
queremos tener los enlaces a1-b2 y a2-b1. Aunque pudiramos cambiar atmicamente
a1-b1 por a1-b2 sin violar la restriccin de multiplicidad para a1, esto dejara a b1 sin
ningn enlace y a b2 con dos enlaces hasta que se alcanzase el estado final. Tendramos
que llevar a cabo todo el cambio de modo atmico por medio de un trueque atmico
implementado en una nica operacin.

1..1

1..1

(a)

a1 : A

b1 : B

a1 : A

a2 : A

b2 : B

a2 : A

(b)

(c)

b1 : B

a1 : A

b2 : B

a2 : A

b1 : B

b2 : B
(d)

Figura 2. Las restricciones de multiplicidad pueden hacer muy difcil el cambio de enlaces entre
instancias sin pasar por un estado errneo del sistema: a) diagrama de clases; b) estado inicial; c)
estado intermedio errneo; d) estado final deseado

Evidentemente, no podemos definir una nueva operacin para evitar cualquier estado
errneo concebible que implique varias instancias. En consecuencia, pensamos que las
asociaciones obligatorias plantean problemas insolubles en lo que se refiere a la creacin y
destruccin de instancias y enlaces: no podemos conseguir con unas pocas operaciones
primitivas que una asociacin obligatoria sea obedecida en todo momento, y no podemos
aislar, dentro de operaciones atmicas, los momentos en los que la restriccin no es
obedecida. Por tanto, tenemos que relajar las implicaciones de las asociaciones obligatorias
para la implementacin, como hacen otros mtodos [Harrison 00]. Nuestra propuesta es la
siguiente: no comprobar la restriccin de multiplicidad mnima al modificar los enlaces de
la asociacin (mtodos mutadores), sino slo al acceder a los enlaces (mtodos lectores).
El programador ser responsable de usar las primitivas de modo consistente, de modo que
se alcance cuanto antes un estado vlido del sistema.
Por ejemplo, estar permitido crear una empresa sin enlazarla a ninguna persona, y
estar permitido borrar todos los enlaces de una empresa con instancias de Persona; pero
antes de acceder, con otros fines, a los enlaces de esa instancia particular de Empresa con
instancias de Persona, ser necesario restaurarlos a un estado vlido, en caso contrario se
obtendr una excepcin de multiplicidad invlida (invalid multiplicity exception), que ser
definida en el cdigo que implemente las asociaciones de acuerdo con nuestra propuesta.
2.2. Asociaciones sencillas y mltiples
El valor de la multiplicidad mxima en un extremo de asociacin puede ser cualquier
entero mayor o igual que 1, aunque los valores ms comunes son 1 y *. Cuando el valor es
1 decimos que la asociacin es sencilla (single) para la clase en el extremo opuesto (clase
Persona en la Figura 1), y decimos que es mltiple (multiple) cuando el valor es 2 o
mayor (clase Empresa). Las asociaciones sencillas son ms fciles de implementar que las
asociaciones mltiples: para almacenar la nica instancia posible de una asociacin sencilla
habitualmente empleamos un atributo que tenga como tipo la correspondiente clase destino,
pero para almacenar los muchos enlaces potenciales de una asociacin mltiple tenemos
que usar algn tipo de coleccin de objetos, tal como las predefinidas en Java Vector,
HashSet, etc. En el caso general no podemos usar un array de objetos, porque su tamao
queda fijado al instanciarlo. Como las colecciones en Java pueden tener cualquier nmero
de elementos, la restriccin de multiplicidad mxima no puede ser establecida en la
declaracin de la coleccin en el cdigo Java, de modo que habr que comprobarla en algn
otro lugar en tiempo de ejecucin.

6
Necesitamos dos tipos de mtodos mutadores, add (aadir) y remove (borrar), que
aceptarn como parmetro un nico objeto o una coleccin. Debido a los problemas con la
multiplicidad mnima explicados ms arriba, el mtodo borrador a veces tendr que dejar a
la instancia origen en un estado errneo; no podemos evitar esta situacin. El mtodo
aadidor, en cambio, nos permite un cierto grado de eleccin. Si intentamos aadir algunos
enlaces por encima de la restriccin de multiplicidad mxima, podemos elegir entre
rechazar la adicin o llevarla a cabo; en el ltimo caso violamos temporalmente la
restriccin hasta que una llamada al mtodo borrador restaure la instancia origen a un
estado seguro; el estado errneo slo sera detectado por los mtodos lectores, tal como
establecimos en el caso de la multiplicidad mnima. Sin embargo, esto vale slo para
asociaciones mltiples implementadas mediante una coleccin; en asociaciones sencillas
simplemente no podemos violar la restriccin de multiplicidad mxima: estamos obligados
a rechazar la adicin.
Si decidimos rechazar la adicin, en cambio, adems de tener un comportamiento
asimtrico entre el mtodo borrador y el mtodo aadidor, podemos encontrar problemas de
precedencia al invocar el aadidor y el borrador uno detrs de otro. Consideremos la clase
Juego asociada con la clase Participante con multiplicidad 2..4 (ver Figura 3), y
supongamos que una instancia j1 de Juego est enlazada con dos instancias p1, p2 de
Participante. Queremos reemplazar estos dos participantes por cuatro nuevos
participantes diferentes, q1, q2, q3, q4. Si ejecutamos primero borrar, luego aadir,
obtenemos finalmente lo que queremos; pero si ejecutamos primero aadir, luego borrar,
la adicin es rechazada y el borrado deja la instancia de Juego en un estado errneo.

Juego

0..*

2..4

Participante

(a)

q1 : Participante

p1 : Participante
j1 : Juego

q2 : Participante
j1 : Juego

j1 : Juego
p2 : Participante

q3 : Participante

q4 : Participante
(b)

(c)

(d)

Figura 3. Problemas de precedencia al invocar sucesivamente el mtodo aadidor y el mtodo


borrador: a) diagrama de clases de la asociacin Juego-Participante; b) estado inicial con
participantes p1, p2; c) estado final deseado despus de borrar los participantes p1, p2 y luego
aadir los participantes q1, q2, q3, q4; d) estado final incorrecto despus de intentar aadir sin xito
los participantes q1, q2, q3, q4 y luego borrar los participantes p1, p2.

Al final hemos preferido rechazar la adicin si viola el mximo permitido, y pedir a los
usuarios de los mtodos mutadores que los usen siempre en el orden correcto, primero
borrar, luego aadir, de modo que obtengamos un comportamiento anlogo para
asociaciones sencillas y mltiples. As pues, el mtodo borrador no comprueba la
restriccin de multiplicidad mnima (tal vez dejando vaca una asociacin obligatoria), el

7
mtodo aadidor s comprueba la restriccin de multiplicidad mxima, y el mtodo lector
levanta una excepcin si cualquiera de las restricciones no se satisface.
Los mtodos lectores de las asociaciones mltiples tienen otra peculiaridad, cuando se
comparan con los de las asociaciones sencillas: devuelven una coleccin de objetos, no un
nico objeto, y por tanto el tipo del valor de retorno es el de la coleccin, no el de la clase
destino. En nuestra implementacin el tipo devuelto es la interfaz Collection de Java,
implementada por todas las colecciones estndar. Internamente usamos una coleccin
HashSet, que asegura que no hay enlaces duplicados en una asociacin, tal como exige
UML [UML, p. 2-19] 7.
Finalmente, las colecciones estndar en Java estn especificadas para contener
instancias de la clase estndar Object, que es superclase de todas las dems clases en
Java. No es posible especializar estas colecciones para que almacenen objetos que
pertenezcan slo a una clase determinada8. Esto significa que, si utilizamos un HashSet
dentro de Empresa para almacenar los enlaces con Persona, debemos asegurar por
nuestra cuenta que nadie pone un enlace a una instancia de otra clase como Perro o
Informe (esto podra ocurrir si se pasa como parmetro una coleccin de objetos al
mtodo add). As pues, los mtodos mutadores deben realizar una comprobacin de tipos
por medio de un moldeado (casting) explcito en tiempo de ejecucin. Si falla la
comprobacin de tipos, entonces no se actualiza el enlace a ese objeto, y se levanta una
excepcin de molde de clase (class cast exception), predefinida en Java.

3. El problema de la navegabilidad
La direccionalidad o navegabilidad de una asociacin binaria, expresada grficamente
mediante una flecha abierta en el extremo de la lnea de la asociacin que conecta las dos
clases, especifica la capacidad que tiene una instancia de la clase origen de acceder a las
instancias de la clase destino por medio de las instancias de la asociacin (enlaces) que las
conectan9. Si la asociacin puede ser recorrida en ambas direcciones, entonces es
bidireccional (two-way), en caso contrario es unidireccional (one-way).
Un extremo de asociacin navegable, referenciado por su nombre de rol, define un
pseudo-atributo de la clase origen, de modo que la instancia origen puede usar el nombre de
rol en expresiones, del mismo modo que usa sus propios atributos [RM, p. 354]. Una
instancia puede comunicarse (enviando mensajes) con las instancias conectadas en los
extremos opuestos navegables, y puede usar referencias a stas como argumentos o valores
de respuesta en las comunicaciones [UML, p. 2-114]. De modo similar, si el extremo de
asociacin es navegable, la instancia origen puede consultar (query) y actualizar (update)
los enlaces que la conectan a las instancias destino.
Los ejemplos de la Figura 4 ilustran la navegabilidad. La asociacin Llave-Puerta
es unidireccional, lo que quiere decir que una llave puede acceder a la puerta que abre, pero
7

Aunque en otros lugares hemos dado argumentos concluyentes en contra de esta


restriccin [Gnova 03b], en la generacin de cdigo hemos respetado la definicin actual
de UML.
8
Es decir, no es posible especializarlas para modificar su estructura de almacenamiento,
pero s es posible modificar su funcionamiento para que, de hecho, slo almacenen los
objetos requeridos, precisamente mediante el mtodo de comprobacin de tipo en tiempo de
ejecucin que estamos describiendo.
9
Una definicin alternativa: la posibilidad que tiene un objeto origen de designar un
objeto destino a travs de una instancia de asociacin (enlace), con el fin de manipularlo o
acceder a l en una interaccin con intercambio de mensajes. El Estndar no contiene una
definicin clara de navegabilidad, como hemos mostrado en trabajos anteriores donde
hemos intentado aclarar este tema [Gnova 01, Gnova 03a, Gnova 03b]. En este artculo
tomamos navegabilidad y direccionalidad como sinnimos.

8
una instancia de Puerta no conoce el conjunto de instancias de Llave que la abren: la
puerta no puede recorrer las conexiones o enlaces en contra de la navegabilidad de la
asociacin. Por otra parte, la asociacin Hombre-Mujer es bidireccional, lo que quiere
decir que las instancias conectadas de estas clases se conocen mutuamente.

Llave

0..*

1..1
abrir

Puerta

(a)

Hombre

0..1
esposo

0..1
esposa

Mujer

(b)

Figura 4. Ejemplos de a) asociacin unidireccional y b) asociacin bidireccional

Las puntas de flecha pueden mostrarse u omitirse en una asociacin bidireccional


[UML, p. 3-73]. Desafortunadamente, esto conduce a una ambigedad en la notacin
grfica, porque no podemos distinguir entre asociaciones bidireccionales y asociaciones sin
navegabilidad especificada. O, peor an, se asume que las asociaciones sin navegabilidad
especificada son bidireccionales sin posterior anlisis.
3.1. Asociaciones unidireccionales
Una asociacin unidireccional sencilla es muy similar a un atributo de valor nico
(single valued attribute) en la clase origen, del tipo de la clase destino: una referencia
incrustada, puntero, o como quiera denominrselo. La equivalencia, no obstante, no es
completa. Mientras que el valor del atributo es posedo por la instancia de la clase y no
tiene identidad, un objeto externo referenciado tiene identidad y puede ser compartido por
instancias de otras clases que tengan referencias a ese mismo objeto [Rumbaugh 96b] (ver
Figura 5). En todo caso, la equivalencia es suficientemente satisfactoria como para servir de
base para la implementacin de este tipo de asociaciones. En realidad, en Java no hay
ninguna diferencia: excepto en el caso de los valores primitivos, los atributos en Java son
objetos con identidad, y si son pblicos no se puede evitar que sean referenciados y
compartidos por otros objetos.
Persona
nacimiento: Fecha
(a)

Persona

0..1
nacimiento

Fecha

1..1
publicacin

Libro

(b)

Figura 5. Equivalencia parcial entre a) atributo y b) asociacin unidireccional sencilla

9
Una asociacin unidireccional mltiple es algo ms complicada, aunque la
implementacin puede basarse en los mismos principios, ya que puede asimilarse a un
atributo multivaluado (multivalued attribute)10. Sin embargo, para gestionar la coleccin de
objetos en el extremo navegable necesitamos un objeto adicional de una clase coleccin
estndar, que en nuestra implementacin es la clase HashSet (ver Figura 6).

Receta

1..*
Alimento
ingrediente
(a)

Receta

1..1

Alimento

ingrediente

HashSet

1..*
element

Object

(b)

Figura 6. Asociacin unidireccional mltiple: a) diagrama de anlisis y b) diagrama de diseo. Es


necesario insertar un nuevo objeto para gestionar la coleccin de objetos destino. Las colecciones
estndar en Java, tales como HashSet, estn definidas para la clase estndar Object, que es
superclase de todas las clases; por tanto, los mtodos mutadores deben asegurar que los objetos
contenidos en el parmetro coleccin son del tipo apropiado antes de aadirlos al atributo coleccin.

As pues, el tipo del atributo usado para implementar la asociacin dentro de la clase
origen ya no es la clase destino misma, sino la clase HashSet u otra clase coleccin
conveniente. Los mtodos para gestionar la asociacin tendrn que llevar al cabo algunas
tareas adicionales. Los mtodos mutadores pueden aadir o borrar no slo objetos
singulares de la clase destino, sino tambin enteras colecciones; as, el tipo del parmetro
ser o bien la clase destino de la asociacin o bien la clase coleccin intermedia. En este
caso, los mtodos mutadores deben asegurar que los objetos contenidos en el parmetro
coleccin son del tipo apropiado antes de aadirlos al atributo coleccin. Los mtodos
lectores, como ya hemos explicado (ver Seccin 2), no devuelven un objeto singular, sino
una coleccin de objetos, aunque est formada por un solo elemento. El objeto coleccin
devuelto no es idnticamente el mismo que el que est almacenado dentro de la clase
origen, sino un clon (un nuevo objeto con una coleccin de referencias a los mismos
elementos destino), porque el objeto coleccin original debe permanecer completamente
encapsulado dentro del objeto origen (esto se representa como una composicin en la
Figura 6).
Como muestran los diagramas de las Figuras 4 y 5, en nuestra opinin la restriccin de
multiplicidad en un diagrama de diseo slo puede especificarse en el extremo de

10

UML permite la multiplicidad en atributos, y por tanto los atributos multivaluados


[UML, p. 2-50].

10
asociacin navegable11. En efecto, la multiplicidad es una restriccin que debe ser evaluada
en el contexto de la clase que posee el extremo de la asociacin; si esta clase conoce la
restriccin, entonces conoce el extremo de asociacin, es decir, el extremo es navegable.
No se puede restringir el nmero de objetos conectados a una instancia dada a menos que
esta instancia tenga algn conocimiento de los objetos conectados, es decir, a menos que se
haga navegable el extremo de asociacin. Por tanto, la necesidad de una restriccin de
multiplicidad distinta de 0..* (es decir, no restringida) es una indicacin de que el extremo
de asociacin debe ser navegable. En consecuencia, las asociaciones unidireccionales con
restricciones de multiplicidad en el extremo de asociacin no navegable deben ser
rechazadas en la generacin de cdigo.
3.2. Asociaciones bidireccionales
La equivalencia parcial entre atributos y asociaciones unidireccionales ya no la
encontramos entre las asociaciones bidireccionales. En su lugar, una instancia de una
asociacin bidireccional es ms parecida a una tupla de elementos [UML, p. 2-19].
Combinando las multiplicidades en ambos extremos de asociacin, podemos tener tres
casos: sencilla-sencilla, sencilla-mltiple, y mltiple-mltiple.
Una forma fcil de implementar una asociacin bidireccional sencilla-sencilla es por
medio de dos asociaciones unidireccionales sencillas sincronizadas (ver Figura 7). La
sincronizacin de las dos mitades debe ser preservada por los mtodos mutadores en cada
lado: cada vez que se solicita una actualizacin en un lado, el otro lado debe ser informado
para realizar la correspondiente actualizacin; sta es llevada a cabo slo si ambos lados
estn de acuerdo en que pueden ejecutarla manteniendo las restricciones de multiplicidad
mxima12 (ver Figura 8).

Hombre

0..1
esposo

0..1
esposa

Mujer

(a)

esposa
0..1
Hombre

{sincronizado}

Mujer

0..1
esposo

(b)

Figura 7. Asociacin bidireccional sencilla-sencilla: a) diagrama de anlisis y b) diagrama de diseo.


La implementacin de los mtodos mutadores de la asociacin debe asegurar que el esposo de la
esposa de un cierto hombre es ese hombre mismo, y viceversa

11

Este principio no es aplicable a los modelos de anlisis, que habitualmente no tratan


con la navegabilidad [Fowler 97, Stevens 00]. Evidentemente, la generacin de cdigo slo
tiene sentido a partir de diagramas de diseo.
12
Ya hemos justificado en la Seccin 2 que debe permitirse a los mtodos mutadores
que violen la restriccin de multiplicidad mnima.

11

Mara : Mujer

Juan : Hombre

: Oficial
resultado:= add(Juan)

[esposo=null]:
resultado:= add(self)
[esposa=null]
:esposa=Mara
[resultado=ok]:
esposo=Juan

Figura 8. Diagrama de secuencia que ilustra la sincronizacin de una asociacin bidireccional. La


actualizacin del atributo Mujer.esposo a Juan (ltima operacin) slo tiene lugar despus de
que la actualizacin del atributo Hombre.esposa ha sido correctamente realizada. Si la mujer ya
estuviera casada, entonces no solicitara al hombre que actualizara la asociacin de matrimonio en su
lado; si la actualizacin en el lado del hombre falla (porque ya est casado), entonces la mujer no
actualiza su lado. Para lograr este comportamiento, el mtodo add devuelve un resultado conveniente
que es comprobado por el objeto cliente

Una asociacin bidireccional sencilla-mltiple puede implementarse de modo similar,


combinando una asociacin unidireccional sencilla con una asociacin unidireccional
mltiple. Y, finalmente, una asociacin bidireccional mltiple-mltiple se consigue
mediante dos asociaciones unidireccionales mltiples (ver Figura 9).

Persona

1..3
autor

0..10
publicacin

Libro

(a)

1..1
HashSet
publicacin

{sincronizado}

Persona

Object

0..10
element

1..3
element

HashSet

Object

Libro

1..1
autor

(b)

Figura 9. Asociacin bidireccional mltiple-mltiple: a) diagrama de anlisis y b) diagrama de diseo

La sincronizacin se vuelve progresivamente ms complicada cuando uno o dos de los


extremos de asociacin es mltiple. Consideremos el ejemplo de la Figura 9. Supongamos
que queremos aadir un autor a cierta instancia de Libro; para ello invocamos el mtodo

12
add en la instancia de Libro, pasando una instancia de Persona como parmetro. Si el
libro puede tener ms autores sin violar su multiplicidad mxima (que es 3), entonces
solicita al autor que aada el libro mismo a la coleccin de publicaciones de la persona;
esto puede fallar si la restriccin de multiplicidad mxima para el nmero de publicaciones
(en este caso, 10) es violada. Si la solicitud al autor tiene xito, entonces el libro actualiza
su lado.
Ahora bien, podemos intentar tambin aadir una coleccin de autores a un libro. Como
podramos esperar, el libro solicita a cada uno de los autores que aada el libro mismo
como publicacin; si cualquiera de los autores falla en aadir el libro, entonces toda la
operacin debe ser deshecha, ya que una actualizacin debe ser atmica: todo o nada.
Consideraciones similares afectan al mtodo mutador remove, teniendo en cuenta que
ste es ejecutado aunque la restriccin de multiplicidad mnima no sea satisfecha, y por
tanto puede dejar a la instancia origen o alguna de las instancias destino afectadas en un
estado invlido.
En UML una asociacin se define como un conjunto de tuplas [UML, p. 2-19], lo que
quiere decir que no podemos tener dos veces la misma tupla en la coleccin de enlaces de
una asociacin13. Esto queda automticamente salvaguardado si seguimos el esquema de
implementacin explicado ms arriba. En todo caso, tambin sugiere un tipo diferente de
implementacin que podra tener algunas ventajas. En lugar de sincronizar dos asociaciones
unidireccionales para obtener una bidireccional, podemos almacenar directamente la
coleccin de enlaces bidireccionales (ver Figura 10).

Persona
1..1

1..1
1..1
singleton
asociacinPL AsociacinPersonaLibro asociacinPL

autor

Libro

publicacin 1..1
tupla

0..*

EnlacePersonaLibro

Figura 10. Un esquema alternativo para implementar asociaciones bidireccionales por medio de una
coleccin de tuplas cosificadas

En este esquema alternativo los enlaces estn cosificados y se transforman en objetos


en s mismos [Rumbaugh 87]. Para gestionar la coleccin de enlaces, o tuplas, necesitamos
un objeto, que sea la nica instancia de una clase (aplicando el patrn de diseo Singleton
[Gamma 94]) y que representa a la asociacin misma. La principal ventaja de este enfoque
es que evita la dispersin de la informacin acerca de las instancias de la asociacin
(enlaces), de modo que las actualizaciones se efectan en un nico sitio, sin problemas de
sincronizacin. Se puede extender fcilmente para implementar clases-asociacin y
asociaciones de mayor grado (ternarias, etc.). Sin embargo, estas ventajas tienen un alto
coste, como podemos apreciar comparando las Figuras 9 y 10.
En primer lugar, ntese que las restricciones de multiplicidad originales no estn
expresadas en este esquema: la multiplicidad de los roles Persona.asociacinPL y
Libro.asociacinPL deben ser obviamente 1..1, ya que slo hay una instancia del
objeto que gestiona la asociacin considerada como coleccin de enlaces; adems, un
enlace es la conexin de dos instancias, por tanto un enlace tiene exactamente una pata en
13

La conveniencia de esta restriccin, heredada del Modelo Entidad-Relacin, es


discutida por muchos autores [Genilloud 99, Stevens 02, Gnova 03b].

13
cada lado [Gnova 02, Gnova 03b], es decir, las multiplicidades deben ser 1..1 en los roles
autor y publicacin; finalmente, el rol tupla tiene multiplicidad 0..* sea cual sea la
multiplicidad de la asociacin original, aunque fuera sencilla-sencilla, porque almacena
todos los enlaces que pueden existir entre cualesquiera dos instancias en cada lado. En
consecuencia, las restricciones de multiplicidad resultan ms difciles de mantener, puesto
que el control no puede consistir simplemente en contar enlaces.
Otro problema que encontramos es que la unicidad de cada tupla, exigida por la
restriccin conjunto de tuplas, no queda automticamente salvaguardada. Supongamos
que implementamos la coleccin de tuplas mediante un HashSet de objetos, donde cada
objeto almacena dos referencias, autor y publicacin. Como cada objeto tupla tiene
su propia identidad, dos tuplas diferentes que referencien los mismos dos objetos destino
seran consideradas como objetos diferentes, de modo que la coleccin HashSet no
comprobara por nosotros la unicidad de cada tupla14.
Considerando todos estos factores, en nuestra implementacin hemos descartado el
enfoque de tuplas cosificadas en favor del anterior esquema de referencias cruzadas
sincronizadas.

4. El problema de la visibilidad
Hasta ahora hemos tratado slo con la implementacin en Java de dos propiedades de
las asociaciones UML: multiplicidad y navegabilidad (direccionalidad), pero tambin
estamos interesados en la implementacin de la visibilidad. De acuerdo con el Estndar
[UML, p. 2-23], la visibilidad de un extremo de asociacin especifica la visibilidad del
extremo de asociacin desde el punto de vista del clasificador en el otro extremo. El
Estndar asimila la visibilidad de un extremo de asociacin a la visibilidad de un atributo, y
da las mismas cuatro posibilidades:
 public - otros clasificadores pueden navegar la asociacin y usar el nombre de rol
en expresiones, de modo similar al uso de un atributo pblico.
 protected - los descendientes del clasificador origen pueden navegar la
asociacin y usar el nombre de rol en expresiones, de modo similar al uso de un
atributo protegido.
 private - slo el clasificador origen puede navegar la asociacin y usar el nombre
de rol en expresiones, de modo similar al uso de un atributo privado.
 package - los clasificadores que estn en el mismo paquete (o paquete anidado,
hasta cualquier nivel) que la declaracin de la asociacin pueden navegar la
asociacin y usar el nombre de rol en expresiones15.
En Java encontramos los mismos cuatro tipos de visibilidad para atributos y mtodos
(no es casualidad, por supuesto), denominados niveles de control de acceso (access control
levels) [Gosling 96, Arnold 00], aunque su significado no es exactamente el mismo que en

14

En todo caso, no es una dificultad insalvable. Para que dos tuplas iguales sean
reconocidas como tales y as garantizar su unicidad, es necesario redefinir los mtodos
equals y hashCode, heredados de la clase Object, y empleados por la coleccin
HashSet con este fin [Eckel 00].
15
Este ltimo tipo de visibilidad, aadido en la versin 1.4 del Estndar, est definida
de modo ambiguo, puesto que podra declararse una asociacin entre clasificadores de dos
paquetes diferentes. Entonces, a qu paquete pertenece la declaracin de la asociacin?
Sugerimos esta otra redaccin (adiciones en cursiva): Los clasificadores que estn en el
mismo paquete (o paquete anidado, hasta cualquier nivel) que el clasificador origen pueden
navegar la asociacin y usar el nombre de rol en expresiones, de modo similar al uso de un
atributo con visibilidad de paquete.

14
UML16. La opcin por defecto, obtenida cuando no se especifica el control de acceso, es la
visibilidad de paquete (habitualmente conocida en Java como friendly). Como hemos
implementado las asociaciones UML mediante atributos y mtodos Java, parece que no
deberamos encontrar especiales problemas con la implementacin de la visibilidad17; al
contrario, debera ser ms bien fcil.
Esto es verdad para asociaciones unidireccionales: si declaramos los atributos y
mtodos Java con el mismo control de acceso que el extremo de asociacin UML que
queremos implementar, automticamente obtenemos el comportamiento deseado. Pero la
historia es diferente para asociaciones bidireccionales. En principio, parece razonable
declarar privado uno o dos de los extremos de una asociacin binaria. Podemos pensar en
una asociacin con dos extremos privados como una relacin secreta que no es conocida
fuera de las clases participantes, tal como una asociacin Banco-Cliente, por ejemplo.
De modo similar, una asociacin con un extremo pblico y otro privado sera slo
parcialmente conocida desde el exterior. Pero hay problemas. Consideremos la asociacin
bidireccional Profesor-Materia con visibilidades pblica y privada (ver Figura 11).

Profesor

0..*
+profesor

0..*
-materia

Materia

Figura 11. Una asociacin bidireccional con un extremo de asociacin pblico y otro privado

El extremo de asociacin pblico, profesor, puede ser usado por cualquier otra clase
en el modelo que tenga visibilidad hacia la clase Materia, es decir, la coleccin de
profesores que ensean una determinada materia puede ser consultada y actualizada
directamente por cualquier clase en el modelo que vea la materia. En cambio, el extremo de
asociacin privado, materia, que significa la coleccin de materias que ensea un
determinado profesor, es conocido slo por el profesor mismo, exactamente igual que un
atributo privado. La clase Profesor podra declarar pblicos otros mtodos que
internamente se refirieran al nombre de rol materia, proporcionando de esta manera
acceso indirecto al extremo de asociacin privado, pero el acceso directo est restringido a
la clase poseedora misma. Esto no es ms que la idea de declarar privada alguna cosa.
Ahora bien, aqu tenemos una paradoja en relacin con la bidireccionalidad de la
asociacin. El extremo de asociacin con el nombre de rol privado materia slo es
conocido por su poseedor, es decir, la clase Profesor. Repetimos, slo por su poseedor.
Esto significa que la clase Materia no conoce el extremo de asociacin materia! La
clase Materia conoce que est asociada con la clase Profesor, pero no conoce que la
clase Profesor est a su vez asociada con ella. Es esto realmente una asociacin
bidireccional?
En nuestra implementacin, basada en referencias cruzadas sincronizadas como hemos
explicado ms arriba, esta paradoja se manifiesta en la imposibilidad de actualizacin
recproca de los extremos de asociacin. Recurdese que, cuando una instancia de
Materia intenta aadir una instancia nuevoProfesor de Profesor a su coleccin de
16

El control de acceso protected significa en Java la unin de las visibilidades


protected y package de UML, es decir, el elemento protegido es accesible tanto a los
descendientes como a otros elementos del mismo paquete [Arnold 00, Eckel 00, Gosling
96].
17
Salvo que el significado de protected ser el de Java, no el de UML. El Estndar
reconoce que todas las formas de visibilidad no pblica son de hecho dependientes de la
implementacin [UML, p. 3-42].

15
profesores (profesor.add(nuevoProfesor)), primero tiene que invocar el mtodo
add en el lado recproco (profesor.materia.add(self)) 18; pero esto ahora resulta
imposible debido a la visibilidad privada del extremo de asociacin materia. Lo mismo
ocurre con el mtodo remove. Por el contrario, si una instancia de Profesor intenta
actualizar la asociacin, puede invocar el mtodo de actualizacin en el lado opuesto,
porque es pblico, y puede actualizar su propio lado privado, de modo que toda la
operacin tiene xito. A primera vista, pues, pareca que la asociacin poda ser gestionada
a travs de la clase poseedora del extremo de asociacin pblico (en este caso, la clase
Materia), pero esto ha resultado ser falso: en realidad, slo la clase que posee el extremo
de asociacin privado (Profesor) puede gestionar la asociacin, y el acceso directo
desde fuera de las dos clases participantes es imposible. No obstante, como hemos
explicado ms arriba, la clase Profesor podra declarar mtodos pblicos para
proporcionar acceso indirecto al extremo de asociacin privado desde el exterior.
An peor, si ambos extremos de asociacin fueran privados, como en el ejemplo
Banco-Cliente, la asociacin resultara inaccesible desde ambos lados19. El enfoque
basado en tuplas cosificadas tampoco soluciona el problema, ya que implica clases
auxiliares que no pueden proporcionar acceso privado a las clases principales,
excluyendo a todas las dems clases.
Resumiendo, una asociacin bidireccional pblica-privada puede ser gestionada slo
desde la clase que posee el extremo privado, y todas las dems clases, incluyendo la clase al
otro extremo de la asociacin, slo pueden tener acceso indirecto si esta clase proporciona
los mtodos pblicos adecuados. Una asociacin bidireccional privada-privada, por el
contrario, no puede ser gestionada de ninguna manera. Se pueden hacer consideraciones
similares para las visibilidades de paquete y protegida, que se comportan a estos efectos
respectivamente como las visibilidades pblica y privada. En consecuencia, las
asociaciones bidireccionales con visibilidad distinta de public o package en ambos
extremos deben ser rechazadas en la generacin de cdigo. Pensamos que este resultado no
slo est influenciado por nuestra particular implementacin, sino que se trata de una
dificultad semntica real de la definicin de visibilidad en asociaciones bidireccionales. La
visibilidad en UML no se especifica para asociaciones sino para extremos de asociacin, y
est asimilada a la visibilidad de los atributos [UML, p. 2-23]. Necesitamos en UML una
definicin de visibilidad que encaje mejor con el concepto de asociacin bidireccional.

5. Una interfaz uniforme


El cdigo requerido para implementar una asociacin UML consiste bsicamente en una
adecuada combinacin de atributos y mtodos Java, pero esta combinacin depende de la
multiplicidad, navegabilidad y visibilidad de la asociacin. Con respecto a la multiplicidad,
para almacenar la nica instancia posible de una asociacin sencilla podemos emplear un
atributo de la correspondiente clase destino, pero para almacenar los muchos enlaces
potenciales de una asociacin mltiple necesitamos algn tipo de coleccin de objetos:
hemos elegido HashSet, porque asegura que no hay objetos duplicados en la coleccin.
Con respecto a la navegabilidad, una asociacin unidireccional se implementa slo en la
clase origen, mientras que una asociacin bidireccional se implementa en las dos clases,
con cdigo que asegura la sincronizacin de ambos extremos. La visibilidad de los
extremos de asociacin se traduce directamente en la visibilidad de los mtodos requeridos;
18

Un objeto se refiere a s mismo en UML/OCL mediante la palabra clave self; el


equivalente en Java es this.
19
Una asociacin reflexiva (una asociacin entre instancias de la misma clase) es una
excepcin a esta regla, ya que los extremos de asociacin privados son visibles dentro de la
clase, es decir, para ambos lados de la asociacin.

16
los atributos, en cambio, sern siempre privados, para mantener el acceso controlado a
travs de los mtodos de la interfaz.
Hemos diseado una interfaz uniforme para todo tipo de asociaciones, es decir, una
interfaz tan independiente como sea posible de la multiplicidad, navegabilidad y visibilidad
de los extremos de asociacin. La interfaz comprende mtodos lectores y mutadores, as
como otros mtodos auxiliares para averiguar el estado y definicin de la asociacin.
Nuestra intencin es que el cdigo cliente pueda usar la interfaz de la asociacin sin
conocer a priori, cuando sea posible, de qu tipo de asociacin se trata; esto har el cdigo
cliente mucho ms estable frente a cambios en el diseo (por ejemplo, una asociacin
unidireccional que se transforma en bidireccional).
En realidad la implementacin de asociaciones unidireccionales y bidireccionales es
diferente, porque slo las bidireccionales tienen que estar sincronizadas, pero ambos tipos
presentan exactamente la misma interfaz en cada extremo. Por el contrario, las asociaciones
sencillas y mltiples no slo tienen implementaciones diferentes, sino tambin una interfaz
ligeramente distinta, porque las asociaciones sencillas no manejan colecciones de objetos
como parmetros o valores de retorno. Podramos tratar las asociaciones sencillas como un
caso particular de las asociaciones mltiples y no proporcionar ninguna implementacin o
interfaz especiales para ellas, pero consideramos que se usan con tanta frecuencia que los
beneficios en eficiencia son proporcionados a las prdidas en uniformidad de interfaz.
El los prrafos que siguen, %Target significa el nombre de la clase destino en la
asociacin, que tendr que ser sustituido por su nombre real cuando el cdigo sea generado
para cada asociacin en el modelo de diseo. La clase origen de una asociacin
unidireccional presenta una interfaz para consultar y actualizar el extremo de asociacin
opuesto; la clase destino no presenta ninguna interfaz, porque no tiene conocimiento de la
asociacin. Por el contrario, los dos lados de una asociacin bidireccional presentan una
interfaz; en este caso los trminos origen y destino son relativos a la clase que est
viendo el extremo de asociacin opuesto.
5.1. Mtodos lectores
Tenemos dos mtodos lectores, test y get, con las signaturas siguientes:
 boolean test(%Target query_link);
 boolean test(Collection query_links);
 %Target get();
 Collection get();
El mtodo test comprueba si una instancia dada de la clase destino (el parmetro
query_link) est enlazada con la instancia de la clase origen que recibe la invocacin
del mtodo. La segunda versin de este mtodo se define slo cuando el extremo de
asociacin es mltiple; en este caso el mtodo comprueba si todas las instancias contenidas
en el parmetro coleccin estn enlazadas con la instancia origen20.
El mtodo get devuelve las instancias destino que estn enlazadas con la instancia
origen. La primera versin es para un extremo de asociacin sencillo y devuelve un valor
nico cuyo tipo es la clase destino, mientras que la segunda versin es para un extremo de
asociacin mltiple, y por tanto devuelve un valor de tipo Collection. De acuerdo con
la justificacin dada ms arriba al tratar con los problemas de la multiplicidad, los mtodos
mutadores garantizan que la multiplicidad mxima no es violada, pero en cuanto a la
multiplicidad mnima, puede ocurrir que el nmero de instancias enlazadas sea menor que

20

El parmetro se define de tipo Collection para tener mayor generalidad.


Collection es una abstraccin de los conceptos de lista (list), conjunto (set) y
correspondencia (map). Tcnicamente, es una interfaz realizada por clases de librera tales
como Vector (obsoleta), ArrayList, HashSet, TreeMap y otras.

17
el mnimo requerido por el diseo, en cuyo caso se levanta la excepcin de multiplicidad
invlida21.
5.2. Mtodos mutadores
Tenemos tambin dos mtodos mutadores, remove y add, con las signaturas
siguientes:
 int remove();
 int remove(%Target old_link);
 int remove(Collection old_links);
 boolean add(%Target new_link);
 boolean add(Collection new_links);
El mtodo remove borra las instancias destino del extremo de asociacin opuesto, y
devuelve un cdigo de error conveniente. Puede borrar todas las instancias (primera versin
sin parmetros), una instancia (segunda versin), o una coleccin de instancias (tercera
versin, disponible slo cuando el extremo de asociacin opuesto es mltiple). En la tercera
versin, si cualquiera de las instancias en el parmetro coleccin no es de tipo %Target,
entonces no se borra ningn enlace, siguiendo la semntica de todo o nada, y se levanta
una excepcin de molde de clase (class cast exception). Por el contrario, si alguna de las
instancias de la coleccin (o la nica instancia, en la segunda versin del mtodo)
simplemente no est enlazada a la instancia origen, entonces la operacin prosigue sin
considerarlo un error. En una asociacin bidireccional el mtodo invoca un remove
recproco en cada una de las instancias que hay que borrar. El mtodo remove puede dejar
la instancia origen o alguna de las instancias destino en un estado invlido respecto a las
restricciones de multiplicidad mnima, en cuyo caso se devuelve un cdigo de error, pero
no se levanta ninguna excepcin. Si a continuacin se invocara el mtodo get, se
levantara la excepcin de multiplicidad invlida.
El mtodo add aade una nueva instancia o coleccin de instancias destino en el
extremo de asociacin opuesto, y devuelve un valor boolean para indicar si la operacin
fue ejecutada o no. La segunda versin de este mtodo se define slo cuando el extremo de
asociacin es mltiple; si cualquier instancia del parmetro coleccin no es de tipo
%Target, entonces no se aade ningn enlace, siguiendo la semntica de todo o nada y
se levanta una excepcin de molde de clase (class cast exception). Por el contrario, si
alguna de las instancias de la coleccin (o la nica instancia, en la primera versin del
mtodo) ya est enlazada a la instancia origen, entonces la operacin prosigue sin
considerarlo un error (y, por supuesto, sin aadir un duplicado). En una asociacin
bidireccional, el mtodo invoca un add recproco en cada una de las instancias que hay que
aadir. El mtodo add comprueba si la instancia origen, o alguna de las instancias destino,
sera dejada en un estado invlido respecto a las restricciones de multiplicidad mxima, en
cuyo caso la operacin es cancelada, no se aade ningn enlace, y se devuelve un valor
False22.
Si se desea sustituir algunas instancias destino por otras instancias destino, hay que
invocar primero el mtodo remove y luego el mtodo add; en caso contrario el resultado
podra ser diferente del esperado (ver Seccin 2). Atencin, esto vale incluso para
asociaciones sencillas: no hay ningn remove implcito de la instancia antigua cuando se
21

De hecho, la comprobacin la lleva a cabo el mtodo isValid, que puede ser algo
ms elaborado que simplemente verificar que el nmero de instancias enlazadas no es
menor que el mnimo requerido; el programador puede modificar manualmente el cdigo
de isValid para implementar una restriccin ms compleja.
22
Como en el caso anterior, la comprobacin es ejecutada por el mtodo isValid, que
puede conseguir un comportamiento ms general.

18
aade una nueva (se hace as para obtener un comportamiento lo ms parecido posible entre
asociaciones sencillas y mltiples).
5.3. Mtodos auxiliares para averiguar el estado de la asociacin
Tenemos dos mtodos auxiliares para conocer el estado de la asociacin desde el punto
de vista de una instancia origen particular:
 boolean isValid();
 long numberOfLinks();
El mtodo isValid determina si la instancia origen ve el nmero correcto de
instancias destino en el lado opuesto de la asociacin, de acuerdo con las restricciones de
multiplicidad especificadas en el modelo de diseo. La herramienta genera cdigo slo para
el caso ms sencillo, cuando la restriccin de multiplicidad consiste en un nico intervalo
MIN..MAX. En todo caso, el programador puede modificar manualmente el cdigo para
implementar una restriccin ms compleja, y los cambios afectarn a la ejecucin de los
mtodos lectores y mutadores, ya que ellos comprueban las restricciones de multiplicidad
por medio de este mtodo. Este mtodo tambin es til cuando la comprobacin automtica
de las restricciones de multiplicidad est desactivada y el programador asume la
responsabilidad de comprobarlas manualmente en puntos especficos del cdigo fuente.
El mtodo numberOfLinks devuelve el nmero de instancias destino enlazadas a la
instancia origen.
5.4. Mtodos auxiliares para averiguar la definicin de la asociacin
Tenemos cinco mtodos auxiliares para conocer la definicin de la asociacin desde un
lado de la misma, que pueden ser tiles para el cdigo cliente:
 boolean isBidirectional();
 boolean isMandatory();
 boolean isMultiple();
 long getMIN();
 long getMAX();
El mtodo isBidirectional determina si el extremo de asociacin recproco
tambin es navegable. El mtodo isMandatory determina si la multiplicidad mnima es
mayor que cero. El mtodo isMultiple determina si la multiplicidad mxima es mayor
que uno. El mtodo getMIN devuelve el valor de la restriccin de multiplicidad mnima.
El mtodo getMAX devuelve el valor de la restriccin de multiplicidad mxima. Cundo
sta es muchos (*) se devuelve un valor especial. La interfaz tambin define el valor
constante int MANY (de hecho -1).

6. La herramienta de generacin de cdigo


En esta seccin vamos a presentar brevemente la herramienta que hemos desarrollado:
JUMLA (Java code generator for Unified Modeling Language Associations). Esta
herramienta lee un modelo UML, almacenado en formato XMI, y genera el cdigo Java
para gestionar las asociaciones UML contenidas en el modelo de entrada, de acuerdo con la
tcnica descrita en este artculo. La herramienta slo genera cdigo para asociaciones:
ignora cualquier otro artefacto UML que no est directamente relacionado con las
asociaciones, como generalizaciones entre clases, atributos y operaciones de clase, etc. La
herramienta presenta las clases y asociaciones encontradas en el modelo, y el usuario puede
seleccionar de qu asociaciones quiere que se genere el cdigo.
La herramienta crea ficheros de salida Java para las clases implicadas e inserta en ellas
el cdigo para las asociaciones, con etiquetas convenientes que marcan el principio y fin del
cdigo generado. Si el fichero de la clase ya existe, el cdigo es insertado al final del

19
fichero, respetando cualquier otro cdigo de la clase que el programador pueda haber
escrito manualmente (por el contrario, si el programador cambia el cdigo de la asociacin
y luego lo vuelve a generar, los cambios manuales se pierden).
La Figura 12 muestra un modelo de ejemplo y la Figura 13 muestra cmo se presenta en
la ventana principal de la herramienta JUMLA. El panel izquierdo de la herramienta
muestra las clases contenidas en el modelo, en una estructura en rbol correspondiente a la
estructura de paquetes del modelo. El panel derecho muestra las asociaciones contenidas en
el modelo. Para cada asociacin se presenta la siguiente informacin: clases origen y
destino; nombre de rol (opcional), multiplicidad, navegabilidad y visibilidad de los
extremos de asociacin origen y destino; nombre de asociacin (opcional). El usuario puede
seleccionar con una casilla de verificacin las asociaciones cuyo cdigo quiere generar.

1..1
Universidad

0..1 < estudia en 0..*

Estudiante

0..*
+estudiante
+curso

controla >

0..*
(-)

1..*

Departamento

Curso

+curso

-director 1..1
Profesor
+miembro 1..*

0..3

+profesor
1..2

ensea >

Figura 12. Un modelo de ejemplo con algunas clases y asociaciones entre las clases

Figura 13. Una instantnea de la herramienta JUMLA.

1..*

20
La herramienta funciona de acuerdo con cinco opciones predefinidas que pueden ser
deshabilitadas por el usuario para obtener mayor flexibilidad en la generacin de cdigo o
en el tratamiento del modelo de entrada. La Tabla 1 resume las opciones de la herramienta.
Opcin
Comprobar las restricciones de multiplicidad
mnima y mxima en el mtodo get
Comprobar la restriccin de multiplicidad mxima
en el mtodo add
Comprobar el tipo de los objetos en parmetros
Collection en los mtodos add y remove
Rechazar asociaciones unidireccionales con
restriccin de multiplicidad en el extremo origen
Rechazar asociaciones bidireccionales con un
extremo privado o protegido

Valor por
defecto
S
S
S
S
S

Tabla 1. Resumen de opciones de la herramienta

Las dos primeras opciones se refieren a la comprobacin automtica de restricciones de


multiplicidad en los mtodos mutadores y lectores mediante el mtodo auxiliar isValid.
De acuerdo con la justificacin dada en la Seccin 2, el funcionamiento predefinido es as:
los mtodos lectores (get) levantan una excepcin de multiplicidad invlida (invalid
multiplicity exception), definida en el cdigo que implementa las asociaciones, si no se
satisfacen las restricciones de multiplicidad; los mtodos aadidores (add) rechazan la
adicin de nuevos enlaces si no se satisfacen estas restricciones, pero no levantan ninguna
excepcin; y los mtodos borradores (remove) no hacen ninguna comprobacin. Estas
dos primeras opciones permiten generar un cdigo simplificado que omite estas
comprobaciones, asumiendo el usuario la responsabilidad del control de la multiplicidad.
La tercera opcin de la herramienta se refieren a la comprobacin automtica de tipos
en los mtodos mutadores (add y remove) para asociaciones mltiples, que manejan
parmetros de tipo Collection, por medio de un moldeado (casting) explcito en tiempo
de ejecucin. De acuerdo con la justificacin dada en la Seccin 2, si falla la comprobacin
de tipos, entonces no se actualizan los enlaces, y se levanta una excepcin de molde de
clase (class cast exception), predefinida en Java. Esta tercera opcin permite generar un
cdigo simplificado que no comprueba el tipo de los objetos recibidos en el parmetro
Collection, y no levanta ninguna excepcin.
Las dos ltimas opciones se refieren a la comprobacin de la validez del modelo de
entrada. En el funcionamiento predefinido se rechazan las asociaciones unidireccionales
con restricciones de multiplicidad en el extremo de asociacin no navegable (ver Seccin
3), y las asociaciones bidireccionales con visibilidad distinta de public o package en
ambos extremos (ver Seccin 4). La cuarta opcin permite generar el cdigo sin comprobar
la multiplicidad en el extremo no navegable, en lugar de rechazar la asociacin. La quinta
opcin permite generar el cdigo, en lugar de rechazar la asociacin, cuando uno de los dos
extremos tiene visibilidad protected o private y el otro extremo public o
package, advirtiendo al usuario de que debe proporcionar acceso indirecto por medio de
otros mtodos. Cuando ambos extremos son protected o private, la asociacin
siempre es rechazada, porque el cdigo generado no podra funcionar correctamente.

7. Conclusiones
En este trabajo hemos desarrollado una forma concreta de traducir las asociaciones
UML en cdigo Java: hemos escrito plantillas de cdigo especficas, y hemos construido

21
una herramienta que lee un modelo de diseo UML almacenado en formato XMI y genera
los ficheros Java necesarios. Hemos prestado especial atencin a tres propiedades
principales de las asociaciones: multiplicidad, navegabilidad y visibilidad. Nuestro anlisis
ha encontrado dificultades que pueden revelar algunas debilidades de la Especificacin de
UML.
En lo que respecta a la multiplicidad, hemos mostrado que es imposible en la prctica
con unas pocas operaciones primitivas satisfacer la restriccin multiplicidad mnima en
todo momento en un extremo de asociacin obligatorio; nuestra propuesta es comprobar
esta restriccin slo al acceder a los enlaces, pero no al modificarlos. El programador ser
responsable de usar las primitivas de modo consistente, de modo que se alcance cuanto
antes un estado vlido del sistema. Por el contrario, es posible asegurar el cumplimiento de
la restriccin de multiplicidad mxima en tiempo de ejecucin, de modo que nuestra
implementacin la hace cumplir. Los extremos de asociacin sencillos se almacenan
fcilmente en atributos que tengan como tipo la clase destino, pero los extremos de
asociacin mltiples requieren el uso de colecciones para almacenar el correspondiente
conjunto de enlaces; como las colecciones en Java estn basadas en la clase estndar
Object, es necesario realizar comprobacin de tipos en tiempo de ejecucin por medio de
moldeado (casting) explcito cuando se usan colecciones como parmetros en los mtodos
mutadores.
En lo que respecta a la navegabilidad, las asociaciones unidireccionales son ms fciles
de implementar por medio de atributos que las asociaciones bidireccionales, debido a las
dificultades en la sincronizacin de los dos extremos de la asociacin. Una actualizacin en
una asociacin bidireccional debe ser ejecutada atmicamente en ambos extremos para
mantenerla consistente; esto se consigue en el objeto origen solicitando una actualizacin
recproca en el objeto destino. Hemos considerado los pros y contras de una
implementacin alternativa, basada en el almacenamiento de tuplas cosificadas, y
finalmente la hemos descartado en favor de nuestro esquema de referencias cruzadas
sincronizadas. Una consecuencia derivada de nuestro anlisis es que la restriccin de
multiplicidad en un modelo de diseo slo puede ser especificada para un extremo de
asociacin navegable.
En lo que respecta a la visibilidad, en el caso de asociaciones unidireccionales se
implementa con cierta facilidad simplemente traduciendo la visibilidad del extremo de la
asociacin a la visibilidad de los correspondientes mtodos lectores y mutadores, porque
los niveles de visibilidad de UML y Java tienen la misma semntica. Sin embargo, las
asociaciones bidireccionales con uno o dos extremos privados (o protegidos) se comportan
de modo paradjico, porque la actualizacin recproca resulta imposible. Adems,
consideramos que la visibilidad de paquete est mal definida para las asociaciones en la
Especificacin de UML, y hemos sugerido una nueva definicin.
El cdigo generado para cada asociacin se localiza fcilmente dentro de las clases Java
implicadas. Cada extremo de asociacin presenta una interfaz uniforme para el
programador. La interfaz es exactamente la misma para extremos de asociacin
unidireccionales y bidireccionales, pero hay ligeras diferencias para extremos de asociacin
sencillos y mltiples.
Nuestro enfoque es ms bien exhaustivo en cuanto a las comprobaciones de invariantes.
Pensamos que vale la pena hacer todo lo que se pueda para ayudar al programador, de
modo que nuestra herramienta inserta cdigo que realiza comprobaciones de multiplicidad
y tipo en tiempo de ejecucin y, por supuesto, que solicita las actualizaciones recprocas en
asociaciones bidireccionales. No obstante, la herramienta tiene distintas opciones que
permitirn al usuario omitir las comprobaciones automticas de multiplicidad y tipo al
generar el cdigo, en favor de la eficiencia. Adems, hemos argumentado que las
asociaciones unidireccionales no deberan tener restricciones de multiplicidad en el extremo
origen en un modelo de diseo, y que las asociaciones bidireccionales no deberan tener
ambos extremos con visibilidad privada (o protegida); por tanto, nuestra herramienta

22
rechazar la generacin de cdigo para estas asociaciones. Una vez ms, el usuario podr
desactivar esta comprobacin de correccin del modelo y generar el cdigo por su cuenta y
riesgo.
Este trabajo puede continuarse en distintas lneas. Primero, implementacin de otras
propiedades de los extremos de asociacin, tales como ordenacin, modificabilidad,
especificador de interfaz, asociaciones exclusivas, etc. Segundo, implementacin especfica
de algunos tipos particulares de asociaciones binarias tales como asociaciones reflexivas,
agregaciones y composiciones. Tercero, implementacin de asociaciones ms complejas:
asociaciones cualificadas, clases-asociacin, y asociaciones n-arias. Cuarto, ampliar la
herramienta para que lleve a cabo ingeniera inversa, es decir, obtener las asociaciones entre
clases analizando el cdigo que las implementa. Nuestra herramienta no lleva a cabo
actualmente esta tarea, aunque es muy sencilla y directa si el cdigo ha sido escrito con
nuestras plantillas. Finalmente, adaptar la herramienta y las plantillas de modo que sigan la
nueva Java Metadata Interface (JMI) Specification [JMI].
Agradecimientos. Los autores desean dar las gracias a Perdita Stevens, ya que este
artculo fue escrito principalmente mientras el primer autor estaba visitando el Laboratory
for Foundations of Computer Science (LFCS), parte de la Division of Informatics de la
Universidad de Edimburgo, invitado por ella en febrero-abril de 2002; una versin
preliminar de este trabajo fue presentada en el LFCS Lab Lunch el 23 de abril de 2002. Esta
estancia investigadora fue realizada gracias a la financiacin de la Fundacin Universidad
Carlos III, Madrid, Espaa. Gracias tambin a Jos Miguel Fuentes, Vctor Quintana, David
Fernndez y Vicente Palacios por sus valiosas sugerencias para mejorar este artculo.

Referencias
[Ambler 01]

Scott W. Ambler. An Overview of Object Relationships,


Unidirectional Object Relationships, Implementing One-to-Many
Object Relationships, Implementing Many-to-Many Object
Relationships. A series of tips to be found at IBM Developer Works,
http://www-106.ibm.com/developerworks/.

[Arnold 00]

Ken Arnold, James Gosling, David Holmes. The Java Programming


Language. Addison-Wesley, 3rd ed., 1998.

[Castellani 00]

Xabier Castellani, Henri Habrias, Philippe Perrin. A Synthesis on the


Definitions and Notations of Cardinalities of Relationships, Journal of
Object Oriented Programming, 13(6):32-35 (2000)

[cUML]

Financial Systems Architects (New York, U.S.A.). 3C-Clear Clean


Concise. Submission to OMG. http://www.community-ml.org/.

[Eckel 00]

Bruce Eckel. Thinking in Java, 2nd ed. Prentice-Hall, 2000.

[Fowler 97]

Martin Fowler, Kendall Scott. UML Distilled: Applying the Standard


Object Modeling Language. Addison-Wesley, 1997.

[Fujaba]

The Fujaba CASE Tool, University of Paderborn, http://www.fujaba.de/.

[Gamma 94]

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design


Patterns. Elements of Reusable Object-Oriented Software. AddisonWesley, 1994.

[Genilloud 99]

Guy Genilloud. Informal UML 1.3 - Remarks, Questions, and some


Answers. UML Semantics FAQ Workshop (held at ECOOP99), Lisbon,
Portugal, June 12th 1999.

23
[Gnova 01]

Gonzalo Gnova. Semantics of Navigability in UML Associations.


Technical Report UC3M-TR-CS-2001-06, Computer Science Department,
Carlos III University of Madrid, November 2001, pp. 233-251.

[Gnova 02]

Gonzalo Gnova, Juan Llorens, Paloma Martnez. The Meaning of


Multiplicity of N-ary Associations in UML, Software and Systems
Modeling, 1(2): 86-97, 2002. A preliminary version in: Gonzalo Gnova,
Juan Llorens, Paloma Martnez. Semantics of the Minimum Multiplicity
in Ternary Associations in UML. The 4th International Conference on
the Unified Modeling Language-UML2001, October 1-5 2001, Toronto,
Ontario, Canada. Published in Lecture Notes in Computer Science 2185,
Springer 2001, pp. 329-341.

[Gnova 03a]

Gonzalo Gnova, Juan Llorens, Vicente Palacios. Sending Messages in


UML, Journal of Object Technology, vol.2, no.1, Jan-Feb 2003, pp. 99115, http://www.jot.fm/issues/issue_2003_01/article3.

[Gnova 03b]

Gonzalo Gnova. Entrelazamiento de los aspectos esttico y dinmico en


las asociaciones UML. PhD Thesis, Carlos III University of Madrid,
2003.

[Gosling 96]

James Gosling, Bill Joy, Guy Steele. The Java Language Specification.
Addison-Wesley, 1996.

[Harrison 00]

William Harrison, Charles Barton, Mukund Raghavachari. Mapping


UML Designs to Java. The 15th Annual ACM Conference on ObjectOriented Programming, Systems, Languages, and ApplicationsOOPSLA2000, October 15-19 2000, Minneapolis, Minnesota, United
States. ACM SIGPLAN Notices, 35(10): 178-187. ACM Press, New York,
NY, USA.

[JMI]

Java Community Process. Java Metadata Interface (JMI) Specification,


Version 1.0, June 2002. Available at http://www.jcp.org/.

[Kaindl 99]

Hermann Kaindl. Difficulties in the Transition from OO Analysis to


Design. IEEE Software, 16(5):94-102 (1999).

[McAllister 98] Andrew McAllister. Modeling N-Ary Data Relationships in CASE


Environments, Proceedings of the 7th International Workshop on
Computer Aided Software Engineering, pp. 132-140, Toronto, Canada
(1995). A more recent version in: Complete Rules for N-Ary
Relationship Cardinality Constraints, Data & Knowledge Engineering,
27(3):255-288 (1998).
[Noble 96]

James Noble. Some Patterns for Relationships. In Proceedings of


Technology of Object-Oriented Languages and Systems (TOOLS Pacific
21), Melbourne, 1996. Prentice-Hall.

[Noble 97]

James Noble. Basic Relationship Patterns. In Proceedings of the


European Conference on Pattern Languages of Program Design
(EuroPLOP97). Irsee, Germany, 1997.

[Rhapsody]

The Rhapsody CASE Tool, ILogix, http://www.ilogix.com/.

[RM]

James Rumbaugh, Ivar Jacobson, Grady Booch. The Unified Modeling


Language Reference Manual. Addison-Wesley, 1998.

[Ruiz 02]

Carlos Ruiz del Castillo. Implementacin en Java de asociaciones


binarias UML. Universidad Carlos III de Madrid, Proyecto Fin de

24
Carrera, Ingeniera Informtica (Segundo Ciclo), julio 2002. Tutor:
Gonzalo Gnova.
[Rumbaugh 87] James Rumbaugh. Relations as Semantic Constructs in an ObjectOriented Language, In Proceedings of the ACM Conference on ObjectOriented Programming: Systems, Languages and Applications, pp. 466481, Orlando, Florida, 1987.
[Rumbaugh 96a] James Rumbaugh.: Models for Design: Generating Code for
Associations. Journal of Object Oriented Programming, 8(9):13-17,
February 1996.
[Rumbaugh 96b] James Rumbaugh. A Search for Values: Attributes and Associations.
Journal of Object Oriented Programming, 9(3):6-8, June 1996.
[Song 95]

Il-Yeol Song, Mary Evans, E.K. Park. A Comparative Analysis of


Entity-Relationship Diagrams, Journal of Computer and Software
Engineering, 3(4):427-459 (1995)

[Stevens 00]

Perdita Stevens, Rob Pooley. Using UML: Software Engineering with


Objects and Components. Addison-Wesley, 2000.

[Stevens 02]

Perdita Stevens. On the Interpretation of Binary Associations in the


Unified Modelling Language, Journal on Software and Systems
Modeling, 1(1):68-79 (2002). A preliminar version in: Perdita Stevens.
On Associations in the Unified Modeling Language. The Fourth
International Conference on the Unified Modeling Language, UML2001,
October 1-5, 2001, Toronto, Ontario, Canada. Published in Lecture Notes
in Computer Science 2185, Springer 2001, pp. 361-375.

[UML]

Object Management Group. Unified Modeling Language (UML)


Specification, Version 1.4, September 2001 (Version 1.3, June 1999).
Available at http://www.omg.org/.

[XMI]

Object Management Group. XML Metadata Interchange (XMI)


Specification, Version 1.2, January 2002. Available at
http://www.omg.org/.

También podría gustarte