TESIS DOCTORAL

 

"Entrelazamiento de los aspectos estático y dinámico en las asociaciones UML" (2003)

Dirigida por Prof. Dr. Juan Llorens Morillo

Programa de Doctorado en Ingeniería Informática, Universidad Carlos III de Madrid

 

DESCARGA

·         URL persistente en el Archivo Abierto Institucional de la Universidad Carlos III de Madrid: http://hdl.handle.net/10016/682

·         Directamente desde esta página: ZIP PDF 1380 KB

 

PRINCIPALES PUBLICACIONES RELACIONADAS

 

Revistas internacionales

·         Gonzalo Génova, Juan Llorens, José Miguel Fuentes. "UML Associations: A Structural and contextual View", Journal of Object Technology, 3(7): 83-100, Jul-Aug 2004.

·         Gonzalo Génova, Carlos Ruiz del Castillo, Juan Lloréns. "Mapping UML Associations into Java Code", Journal of Object Technology, 2(5): 135-162, Sep-Oct 2003. 

·         Gonzalo Génova, Juan Lloréns, Vicente Palacios. "Sending Messages in UML", Journal of Object Technology, vol.2, no.1, Jan-Feb 2003, pp. 99-115.

·         Gonzalo Génova, Juan Lloréns, Paloma Martínez. "The meaning of multiplicity of n-ary associations in UML", Journal on Software and Systems Modeling, 1(2): 86-97, 2002.

Congresos internacionales

·         Gonzalo Génova, Juan Llorens, José Miguel Fuentes. "The Baseless Links Problem". Workshop on Consistency Problems in UML-based Software Development II, October 20, 2003, San Francisco, USA. Held in conjunction with The 6th International Conference on the Unified Modeling Language-UML'2003, October 20-24, 2003, San Francisco, California, USA. Published in Blekinge Institute of Technology, Research Report 2003:06.

·         Gonzalo Génova, Juan Lloréns, Paloma Martínez. "Semantics of the minimum multiplicity in ternary associations in UML". The 4th International Conference on the Unified Modeling Language-UML'2001, octubre 1-5 2001, Toronto, Ontario, CanadaPublicado en Lecture Notes in Computer Science 2185, Springer 2001, pp. 329-341.

Informes Técnicos

·         Gonzalo Génova. "Semantics of navigability in UML associations". Informe Técnico UC3M-TR-CS-2001-06, Departamento de Informática de la Universidad Carlos III de Madrid, noviembre 2001, pp. 233-251. 

RESUMEN

En esta Tesis Doctoral hemos desarrollado una investigación acerca del concepto de asociación en el Lenguaje Unificado de Modelado, centrada en tres grandes aspectos teóricos (la multiplicidad, la navegabilidad y la visibilidad) y buscando siempre las consecuencias de su aplicación práctica (la implementación).

¿Qué es una asociación?

Tal vez uno de los frutos más importantes de esta Tesis Doctoral es la clarificación del concepto mismo de asociación. La definición de asociación que da el Estándar en el Glosario de Términos es la siguiente: “una asociación es la relación semántica entre dos o más clasificadores que especifica conexiones entre sus instancias” (UML Specification v. 1.4, p. B-3). A su vez, un enlace se define como “una conexión semántica entre una tupla de objetos; una instancia de una asociación” (p. B-11). El objetivo de este trabajo ha sido precisar el sentido de la palabra “semántica” cuando se usa para definir una asociación o un enlace. ¿Qué es una relación semántica, qué es una conexión semántica? ¿Es lo mismo un enlace que una tupla?

Hemos llegado a la conclusión de que la semántica o significado de toda asociación incluye dos aspectos que están íntimamente entrelazados: el aspecto estático y el aspecto dinámico, relacionados respectivamente con la estructura y con el comportamiento del sistema; estos dos aspectos sirven de base para una nueva clasificación de las asociaciones. También hemos argumentado que, para lograr un mayor desacoplamiento entre los participantes en una asociación, conviene definir una asociación no entre clasificadores, sino entre interfaces (redefiniendo también el concepto de interfaz, ya que su definición actual no lo permite).

El aspecto estático se manifiesta en el “hecho” expresado por el enlace; la existencia del enlace implica la verificación del predicado significado por el nombre de la asociación, y este hecho es parte del estado del sistema. El aspecto dinámico se manifiesta en la posibilidad de comunicación proporcionada por el enlace; la existencia del enlace implica que las instancias se conocen en la dirección en que el enlace es navegable, y por tanto pueden intercambiar mensajes en una interacción, teniendo en cuenta también la visibilidad de las operaciones invocadas. El uso de interfaces flexibiliza el modelado con asociaciones, ya que la asociación puede definirse independientemente de los clasificadores conectados.

Así pues, he aquí nuestra definición: Una asociación es una relación definida entre dos o más interfaces. En cada extremo, la interfaz especifica la estructura y el comportamiento que es posible conocer navegando hacia ese extremo a través de la asociación. La asociación especifica un conjunto de enlaces entre instancias de los clasificadores que realicen las respectivas interfaces en cada extremo. Cada enlace es una conexión entre instancias que declara un hecho (la verificación de un predicado) y proporciona una posibilidad de comunicación (una ruta navegable).

La multiplicidad de las asociaciones

En este Capítulo hemos abordado dos temas principales: la multiplicidad en asociaciones n-arias, y la multiplicidad en asociaciones cualificadas y clases-asociación.

En primer lugar, hemos considerado algunos problemas semánticos de la multiplicidad mínima en las asociaciones n-arias, tal como se expresa actualmente en UML; no obstante, nuestras ideas son suficientemente generales como para ser aplicables a otras técnicas de modelado más o menos basadas en el enfoque Entidad/Relación. La multiplicidad mínima está estrechamente relacionada con la restricción de participación, aunque en el caso de asociaciones n-arias no significa la participación de la clase en la asociación, sino la participación de tuplas de las otras n-1 clases. Más aún, hemos descubierto que esta última participación está definida con incerteza, permitiendo tres interpretaciones conflictivas: participación de tuplas reales, participación de tuplas potenciales, y participación con enlaces cojos.

La única que está (implícitamente) de acuerdo con la documentación de UML es la segunda interpretación, tuplas potenciales, a pesar del efecto rebote de la multiplicidad mínima 1. El Estándar debería clarificar esta cuestión, sin resignarse a una falta de claridad en la definición. Además, si esta segunda interpretación fuera elegida, el Estándar también debería advertir, puesto que este resultado no es intuitivo en absoluto, que una multiplicidad mínima 1 o mayor asignada a una clase fuerza a que todas las potenciales subtuplas de instancias de las clases restantes existan contenidas en alguna n-tupla; por tanto, la multiplicidad mínima sería 0 en casi todas las asociaciones n-arias.

La tercera interpretación, enlaces cojos, que es una variación de la primera, parece intuitiva y tiene también algunas ventajas pragmáticas, aunque está en contradicción con la definición de asociación n-aria en UML (tal vez más con la letra que con el espíritu). Nosotros nos inclinamos a apoyar esta interpretación, teniendo cuidado de especificar que representa asociaciones incompletas, pero no subasociaciones relacionadas restrictivas. Podría permitirse que faltasen hasta n-2 patas, y el valor “desconocido”, “vacío” o “nulo” debería ser considerado como un valor concreto a la hora de aplicar las restricciones impuestas por los valores de multiplicidad. No obstante, este tema merece ser proseguido en una investigación que excede el ámbito de este trabajo.

La eventual clarificación de este punto deja otro problema sin resolver: la participación de cada clase queda inexpresada en el estilo Chen de representar las multiplicidades (que es también el estilo de UML), mientras que el estilo Merise las muestra adecuadamente. Ambos estilos Chen y Merise son correctos, pero describen características diferentes de la misma asociación, que no pueden ser derivadas una de la otra en el caso n-ario, aunque sí están relacionadas por una simple regla de consistencia.

Siendo útiles ambos estilos para entender la naturaleza de las asociaciones, proponemos una sencilla extensión a la notación de las multiplicidades n-arias de UML, que permite la representación de la participación y la dependencia funcional (esto es, los estilos Merise y Chen, o multiplicidad interna y externa en la terminología de CDIF). Puesto que esta notación es compatible con las tres interpretaciones alternativas de la multiplicidad de Chen, su uso no evita en sí mismo la ambigüedad de la definición de multiplicidad: son problemas independientes. Si esta notación fuera aceptada, el Estándar debería modificar también el metamodelo en este sentido, ya que sólo tiene prevista una especificación de multiplicidad en la metaclase AssociationEnd. Si éste no fuera el caso, al menos podría reconocerse que las multiplicidades de Chen no son las únicas restricciones de co-ocurrencia razonables que pueden definirse en una asociación n-aria.

Entender las asociaciones n-arias es un problema difícil en sí mismo. Si las reglas del lenguaje usadas para representarlas no están claras, esta tarea puede hacerse inaccesible. Si la interpretación de las asociaciones n-arias es incierta, la comunicación directa entre los modeladores se hace imposible. Si las implicaciones semánticas de un modelo son ambiguas, los implementadores tendrán que tomar decisiones que no les corresponden, y posiblemente decisiones erróneas. Estas razones son más que suficientes para esperar una definición más precisa de estos temas por parte de UML, que tal vez se consiga en la versión 2.0. De hecho, la propuesta 3C (Clear, Clean, Concise) para la elaboración de la versión 2.0, promovida por la empresa Financial Systems Architects (Nueva York, EE.UU., http://www.community-ml.org/), ya ha asumido nuestras ideas sobre las asociaciones n-arias.

El segundo tema que hemos abordado en este Capítulo es la definición de multiplicidad en asociaciones cualificadas y clases-asociación. Al contrario de lo que ocurre con las asociaciones n-arias, el Estándar sí explica el significado de la multiplicidad mínima en el extremo destino de una asociación cualificada, adoptando el equivalente a la interpretación de tuplas potenciales. Esto apoya la conclusión de que el Estándar asume implícitamente la interpretación de tuplas potenciales para las asociaciones n-arias. Como hemos considerado que, por razones prácticas y por ser más intuitiva, en la multiplicidad n-aria es más conveniente la interpretación de enlaces cojos, hemos intentado aplicarla también a la multiplicidad cualificada. No ha sido posible, porque el concepto de “asociación incompleta” no tiene sentido en una asociación cualificada, ya que no hay ninguna asociación entre la clase origen y el cualificador. Si tuviera sentido en un dominio determinado la representación de una asociación incompleta entre la clase origen y el cualificador, lo propio sería emplear una asociación n-aria, no una asociación cualificada. Así pues, debemos renunciar a la interpretación de enlaces cojos para la multiplicidad cualificada.

La multiplicidad en las clases-asociación se ve afectada por la restricción de que no puede haber tuplas repetidas, como en cualquier otra asociación, lo que dificulta el modelado de algunas situaciones comunes, y específicamente la representación de asociaciones con “lógica temporal”, es decir, predicados que se consideran válidos en un periodo de tiempo determinado. El uso de asociaciones cualificadas en lugar de clases-asociación no parece que ayude a resolver estos problemas, porque en principio también están sometidas a esta restricción. La definición de asociación cualificada en UML, a medio camino entre la asociación binaria y la asociación n-aria, no deja suficientemente claro este punto: si prevalece la analogía binaria, no se pueden repetir las tuplas; si prevalece el aspecto n-ario, sí se pueden repetir.

Finalmente, hemos analizado en detalle la raíz de estas dificultades, que es la definición de asociación como conjunto de tuplas no repetidas, una definición excesivamente influenciada por las metodologías de diseño de bases de datos, que ha sido adoptada en UML sin considerar todas las consecuencias. Hemos mostrado una posible solución para escapar de esta restricción, consistente en insertar una clase asociativa ficticia que permita la repetición de tuplas, pero introduciendo una complejidad innecesaria en los modelos. En todo caso, el análisis del metamodelo, salvando sus contradicciones internas, deja claro que un enlace no es exactamente lo mismo que una tupla: un enlace es una conexión entre dos (o más) objetos, y determina una tupla; todos los enlaces de una asociación son distintos (en cuanto que tienen identidad propia y por tanto son distinguibles), pero dos o más enlaces pueden conectar los mismos objetos y así determinar la misma tupla (pueden tener el mismo contenido de datos). Por tanto, la restricción de que no puede haber tuplas repetidas no se deriva de la propia naturaleza de los enlaces, sino que es una restricción adicional que podría suprimirse sin violentar los principios del lenguaje, siendo fácil recuperarla cuando lo requiera la naturaleza del problema modelado.

La navegabilidad de las asociaciones

En este Capítulo hemos considerado algunos problemas semánticos de las asociaciones y la navegabilidad en UML. Hemos intentado clarificar algunas definiciones, y hemos propuesto soluciones para algunos problemas. Hemos buscado una definición de navegabilidad que falta en la documentación oficial, hemos explorado la relación de la navegabilidad con el envío de mensajes, y hemos examinado en detalle la cuestión de los enlaces de comunicación, subrayando algunos malentendidos y conflictos en la presente definición de UML. Hemos reafirmado el principio de que todo enlace es instancia de una asociación, y nuestro análisis nos ha llevado a la distinción entre asociaciones estructurales y contextuales, y a una nueva definición y aplicación de los estereotipos de asociaciones y enlaces. Hemos señalado la relación entre navegabilidad y dependencia, y hemos examinado la invertibilidad, eficiencia y notación de las asociaciones navegables. También hemos aplicado el concepto de navegabilidad a las asociaciones más complejas (clase-asociación, asociación cualificada y asociación n-aria), un tema que ha sido descuidado en la documentación de UML hasta el momento.

Las asociaciones en los modelos orientados a objetos, y más específicamente en los modelos UML, no son simétricas. Las principales asimetrías que podemos encontrar en las asociaciones son la asimetría lingüística, que consiste básicamente en la no intercambiabilidad entre sujeto y objeto en la expresión verbal que da nombre a la asociación, y que se expresa gráficamente mediante el triángulo de dirección del nombre de la asociación; la asimetría todo-parte, expresada por la propiedad de agregación o composición de la asociación; y la asimetría de comunicación, que significa la dirección en la que se puede obtener conocimiento a través de la asociación, y que está estrechamente relacionada con los conceptos de visibilidad, referencia y navegación. Una asociación puede ser bidireccional en este último sentido (navegable en ambas direcciones), pero esto no la hace simétrica. Estos tres tipos de asimetría son independientes, aunque estén conceptualmente relacionados. Las generalizaciones y dependencias, que son otros tipos de relaciones junto con las asociaciones, son también asimétricas.

 “Navegar” o “recorrer” una asociación es obtener, a través de la asociación, una ruta o referencia al objeto opuesto que permita manejarlo; en otras palabras, formar la expresión de una ruta que designa el objeto (o conjunto de objetos) destino desde un objeto origen. Una vez que el objeto origen tiene un nombre relativo del objeto destino que es válido en el contexto del origen, el origen puede manipular el destino, es decir, puede invocar sus operaciones públicas, obtener o modificar sus atributos públicos, pasarlo como parámetro en mensajes a otros objetos, etc. La navegabilidad, por tanto, es (nuestra definición) la posibilidad de que un objeto origen designe un objeto destino a través de una asociación, con el fin de manipularlo o acceder a él en una interacción con intercambio de mensajes. Esta definición u otra similar debería ser incorporada al Estándar.

La dirección de navegabilidad indica que el objeto en el extremo origen puede conocer otros objetos en el extremo destino a través de la asociación. El objeto que tiene conocimiento de la asociación es responsable de mantener el estado de la asociación y controlar la interacción que puede tener lugar a través de ella. Si ambos extremos tienen conocimiento y son responsables de la asociación, entonces se dice que la asociación es bidireccional (two-way), en caso contrario la asociación es unidireccional (one-way). Una asociación sin navegabilidad (no-way) no tiene sentido.

Para que tenga lugar la comunicación entre objetos se requiere tanto navegabilidad como visibilidad: un objeto puede comunicarse sólo con otros objetos de los que tiene conocimiento, y que han puesto las operaciones deseadas a disposición de sus clientes en sus interfaces. Esta idea debería ser expresada clara y concisamente en el Estándar. La navegabilidad está tan estrechamente relacionada con la capacidad de enviar mensajes, que muy a menudo se identifican estos dos conceptos.

Los distintos tipos de enlaces de comunicación que pueden existir en un modelo plantean la cuestión de si todo enlace es o no instancia de una asociación, y si es necesario que exista una asociación siempre que haya comunicación entre objetos. La distinción entre asociaciones estáticas y dinámicas resulta inadecuada para resolver este problema, ya que en orientación a objetos lo estático y lo dinámico son aspectos de toda asociación, más que la característica definitoria de dos subtipos disjuntos de asociación. En su lugar hemos propuesto la distinción entre asociaciones estructurales y contextuales, que, con una adecuada redefinición de los estereotipos de asociaciones y enlaces, permite mantener el principio de que todo enlace es instancia de una asociación. Esta distinción no está basada en las propiedades estáticas o dinámicas de las asociaciones, puesto que toda asociación está (o al menos puede estar) implicada en la estructura y el comportamiento del sistema modelado. En cambio, nuestra clasificación se basa en el contexto en el que son válidas las asociaciones. La distinción se expresa gráficamente en los diagramas usando los estereotipos tradicionales de asociación y enlace, aunque ya no se aplican a los extremos de asociación y enlace, sino a las asociaciones y enlaces mismos.

Hemos examinado tres propiedades de las asociaciones que dependen de la navegabilidad: dependencia, invertibilidad y eficiencia. Puesto que navegabilidad significa conocimiento, y conocimiento significa tanto comunicabilidad como dependencia, la navegabilidad crea una dependencia desde el origen hacia el destino. Cuando las asociaciones en un modelo son predominantemente unidireccionales, la reutilización de pequeñas partes del modelo resulta más sencilla. Este es el principal argumento en favor de asociaciones unidireccionales como opción por defecto, en lugar de asociaciones bidireccionales como promueve UML. En todo caso, las asociaciones bidireccionales no pueden ser descartadas completamente, ya que a veces las requiere la naturaleza del problema o de la solución.

En algunos lugares del Manual de Referencia la invertibilidad-bidireccionalidad parece ser una propiedad lógica de una asociación (incluso de toda asociación), diferente del hecho de que la asociación sea navegable en ambas direcciones. La navegabilidad no sería una propiedad lógica, sino una propiedad de la implementación que significaría más o menos lo mismo que eficiencia de navegación. Nosotros consideramos, por el contrario, que la posibilidad lógica de navegación es un concepto importante tanto en el análisis como en el diseño. Desde nuestro punto de vista, invertibilidad, bidireccionalidad y navegabilidad en ambas direcciones son sinónimos. La esencia de una asociación es el conocimiento, y el conocimiento puede ser unidireccional, no por cuestión de eficiencia, sino por cuestión de principio. Así pues, la flecha de navegabilidad no debería nunca usarse para significar eficiencia de navegación, especialmente porque esto hace imposible especificar que una asociación no es navegable en absoluto en una dirección.

Entre las tres opciones de presentación recomendadas por el Estándar, pensamos que la mejor práctica es usar sólo el estilo “suprimir todo” para las primeras fases del análisis, y el estilo “mostrar todo” para el análisis detallado y para el diseño. Una conexión sin flechas no debe usarse para significar navegabilidad bidireccional, sino navegabilidad sin decidir o sin especificar.

El concepto de navegabilidad, que en la documentación sólo es tratado en relación con la asociación binaria simple, se puede extender sin excesiva dificultad a la clase-asociación y la asociación cualificada. Por el contrario, no resulta tan sencillo para la asociación n-aria. Hemos sugerido varios tipos de expresiones de navegación, con el fin de aprovechar las ventajas de la multiplicidad n-aria: desde un extremo hacia otro extremo, desde una combinación de n-1 extremos hacia otro extremo (usando una notación semejante a la que existe para asociaciones cualificadas), y desde un extremo hacia la asociación misma.

Aunque tenga sentido utilizar un enlace n-ario como infraestructura de comunicación entre los objetos enlazados, la comunicación en sí misma es un fenómeno intrínsecamente binario, es decir, un mensaje tiene exactamente un emisor y un receptor. Esto impide, por una parte, la emisión conjunta de un mensaje por parte de dos o más objetos, y, por otra parte, la recepción conjunta de mensajes. La representación de un mensaje “binario” enviado a través de un enlace n-ario en un diagrama de colaboración es algo problemática, pero hemos dado algunas reglas sencillas que pueden resolver el problema.

La visibilidad de las asociaciones

En este Capítulo hemos considerado algunos problemas relativos a la visibilidad de las asociaciones. Como ésta está basada en la visibilidad de atributos y operaciones, ha sido necesario aclarar antes un par de cuestiones relativas a la visibilidad en UML en general. En primer lugar, la visibilidad de los atributos y operaciones es una característica especificada para los clasificadores, no para las instancias; es decir, la visibilidad no especifica si un objeto puede ver otro objeto, sino más bien si una propiedad de una clase puede ver otra propiedad de la misma o de otra clase. Por tanto, en el caso de que los objetos emisor y receptor pertenezcan a la misma clase, es posible enviar un mensaje que corresponda a una operación privada, aun cuando esta operación no pertenece a la “interfaz nativa” de la clase, formada por sus operaciones públicas. En segundo lugar, los cuatro tipos de visibilidad existentes no son cuatro niveles progresivamente más restrictivos, aunque la expresión “niveles de visibilidad” lo dé a entender, ya que a veces protected es más restrictivo que package, y en otras ocasiones es al revés.

Las definiciones de visibilidad de extremos de asociación contenidas en el Estándar son poco rigurosas; en su lugar hemos propuesto la siguiente: la visibilidad de un extremo de asociación especifica la visibilidad de la asociación desde el punto de vista de otros clasificadores al navegar la asociación en dirección hacia ese extremo. En UML los extremos de una asociación están equiparados a pseudo-atributos de los clasificadores participantes en la asociación, comprometiendo así la unidad de la asociación como elemento constructivo de los modelos. Consecuentemente, la visibilidad de los extremos de asociación se define de modo similar a la visibilidad de atributos y operaciones, con las mismas cuatro posibilidades, excepto en el caso de la visibilidad de paquete, para la cual se pierde el paralelismo. Para recuperar este paralelismo hemos propuesto una nueva definición de visibilidad de paquete para extremos de asociación, que no depende de dónde se define la asociación, sino de dónde se definen los clasificadores asociados. En todo caso, queda sin resolver el problema de la ambivalencia entre la “asociación” como concepto independiente de los clasificadores asociados, y la “referencia” como elemento incluido en ellos y más o menos equivalente a un atributo.

Por otra parte, la definición de asociaciones bidireccionales entre clasificadores pertenecientes a distintos paquetes resulta problemática. En efecto: en primer lugar, un elemento se define en un único paquete, y puede ser usado fuera de su paquete propietario, pero no modificado. En segundo lugar, una asociación navegable induce una dependencia desde el clasificador origen hacia el clasificador destino, dependencia que afecta a la definición del clasificador origen, de modo que debe ser definida en su mismo paquete; por tanto, el extremo navegable de una asociación debe ser definido en el mismo paquete que el clasificador opuesto. En tercer lugar, no es posible definir una asociación bidireccional entre clasificadores de dos paquetes distintos, ya que esto exigiría definir la asociación (es decir, sus extremos) en cada uno de los dos paquetes, y una asociación debe ser definida en un único paquete, como cualquier otro elemento del modelo. Por lo tanto, una asociación bidireccional sólo puede definirse entre clasificadores que pertenezcan al mismo paquete. Aunque a primera vista puede parecer que esto es una grave limitación de UML, en realidad se trata de una consecuencia natural, aunque poco evidente, del concepto de paquete.

El recurso a la visibilidad de atributos y operaciones es insuficiente para conseguir un eficaz desacoplamiento entre los clasificadores de un modelo, ya que la visibilidad no discrimina entre las distintas asociaciones a las que está conectado un clasificador. Lo ideal sería disponer de una interfaz distinta para cada asociación, de modo que el clasificador conectado en el extremo opuesto tuviera una dependencia limitada a las propiedades incluidas en la interfaz. En UML hay dos mecanismos muy similares (incluso demasiado similares para que tenga sentido conservar la distinción) que permiten abordar este problema: especificador de interfaz, e interfaz propiamente dicha.

El especificador de interfaz da una solución parcialmente adecuada a este problema, especialmente si se adopta la definición matizada que hemos propuesto en este Capítulo; no obstante, la clase origen sigue dependiendo de la clase destino concreta, aunque sólo conozca de ella la parte que revela el especificador de interfaz. En cambio, mediante el uso de una interfaz propiamente dicha se consigue una plena independencia respecto a la clase destino concreta, que puede ser cualquier clase que realice la interfaz; así se consigue, además de especificar la funcionalidad requerida a través de la asociación, compartir el extremo de asociación entre varias clases sin necesidad de crear una superclase. Sin embargo, como una interfaz en UML especifica el comportamiento pero no la estructura del clasificador que la realiza, no está permitido que una interfaz participe en asociaciones bidireccionales, porque esto exigiría que la interfaz tuviera estructura. En todo caso, es razonable extender UML con una noción menos restrictiva de interfaz (algunos la denominan “rol”) que incluya tanto la especificación del comportamiento como la especificación del estado. Efectivamente, el uso de interfaces con comportamiento y estado no sólo ayuda a expresar mejor la interacción requerida a través de una asociación, sino también la estructura requerida, logrando así una mejor integración de los aspectos estático y dinámico de la asociación. Esta nueva noción de interfaz implica así mismo una nueva noción de compatibilidad o realización, que incluya ambos aspectos.

En este sentido, hemos propuesto una nueva definición de asociación que ya no se establece entre clasificadores sino entre interfaces, pudiendo estar cada una de ellas realizada por uno o más clasificadores y permitiendo así gran flexibilidad en el diseño. La interfaz en cada extremo especifica la estructura y el comportamiento que es posible conocer a través de la asociación en ese extremo concreto, y que deben satisfacer los objetos asociados. También hemos presentado una notación que permite distintos niveles de complejidad para expresar una misma asociación con mayor o menor grado de detalle; en los niveles más sencillos las interfaces no se muestran, o se muestran de forma reducida; en los niveles sucesivos se muestran con mayor detalle y se realza su papel en los extremos de la asociación.

Finalmente, hemos aplicado este nuevo concepto de asociación, mostrando cómo su uso permite la simplificación de la visibilidad de atributos y operaciones, y resuelve los inconvenientes de la visibilidad privada para asociaciones reflexivas. También hemos mostrado la relevancia de que una interfaz esté conectada sólo a una asociación, o a más de una.

La implementación de las asociaciones

En este Capítulo hemos desarrollado una forma concreta de traducir las asociaciones UML a código Java: hemos escrito plantillas de código específicas, y hemos construido una herramienta que lee un modelo de diseño UML almacenado en formato XMI y genera los ficheros Java necesarios. Hemos prestado especial atención a tres propiedades principales de las asociaciones: multiplicidad, navegabilidad y visibilidad. Nuestro análisis ha encontrado dificultades que pueden revelar algunas debilidades de la especificación de UML.

En lo que respecta a la multiplicidad, hemos mostrado que en la práctica es imposible satisfacer en todo momento la restricción de multiplicidad mínima en un extremo de asociación obligatorio con unas pocas operaciones primitivas; nuestra propuesta es comprobar esta restricción sólo 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 válido del sistema. Por el contrario, es posible asegurar el cumplimiento de la restricción de multiplicidad máxima en tiempo de ejecución, de modo que nuestra implementación la hace cumplir. Los extremos de asociación sencillos se almacenan fácilmente en atributos que tengan como tipo la clase destino, pero los extremos de asociación múltiples requieren el uso de colecciones para almacenar el correspondiente conjunto de enlaces; como las colecciones en Java están basadas en la clase estándar Object, es necesario realizar comprobación de tipos en tiempo de ejecución por medio de moldeado (casting) explícito cuando se usan colecciones como parámetros en los métodos mutadores.

En lo que respecta a la navegabilidad, las asociaciones unidireccionales son más fáciles de implementar por medio de atributos que las asociaciones bidireccionales, debido a las dificultades en la sincronización de los dos extremos de la asociación. Una actualización en una asociación bidireccional debe ser ejecutada atómicamente en ambos extremos para mantenerla consistente; esto se consigue en el objeto origen solicitando una actualización recíproca en el objeto destino. Hemos considerado los pros y contras de una implementación 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 análisis es que la restricción de multiplicidad en un modelo de diseño sólo puede ser especificada para un extremo de asociación 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 asociación a la visibilidad de los correspondientes métodos lectores y mutadores, porque los niveles de visibilidad de UML y Java tienen aproximadamente el mismo significado (salvo el caso de protected en Java, que equivale a la unión de las visibilidades protected y package de UML). Sin embargo, las asociaciones bidireccionales con uno o dos extremos privados (o protegidos) se comportan de modo paradójico, porque la actualización recíproca resulta imposible.

El código generado para cada asociación se localiza fácilmente dentro de las clases Java implicadas. Cada extremo de asociación presenta una interfaz uniforme para el programador. La interfaz es exactamente la misma para extremos de asociación unidireccionales y bidireccionales, pero hay ligeras diferencias para extremos de asociación sencillos y múltiples.

Nuestro enfoque es más bien exhaustivo en cuanto a las comprobaciones de invariantes. Pensamos que vale la pena hacer todo lo que se pueda por el programador, de modo que nuestra herramienta inserta código que realiza comprobaciones de multiplicidad y tipo en tiempo de ejecución y, por supuesto, que solicita las actualizaciones recíprocas en asociaciones bidireccionales. No obstante, la herramienta tiene distintas opciones que permitirán al usuario omitir las comprobaciones automáticas de multiplicidad y tipo al generar el código, en favor de la eficiencia. Además, hemos argumentado que las asociaciones unidireccionales no deberían tener restricciones de multiplicidad en el extremo origen en un modelo de diseño, y que las asociaciones bidireccionales no deberían tener ambos extremos con visibilidad privada (o protegida); por tanto, nuestra herramienta rechazará la generación de código para estas asociaciones. Una vez más, el usuario podrá desactivar esta comprobación de corrección del modelo y generar el código por su cuenta y riesgo.