Es sorprendente cuánta confusión existe sobre la distinción entre la parte y el todo : agregación y composición de conceptos de asociación . El principal problema es el malentendido generalizado (incluso entre los desarrolladores de software expertos y entre los autores de UML) de que el concepto de composición implica una dependencia del ciclo de vida entre el todo y sus partes, de modo que las partes no pueden existir sin el todo. Pero esta visión ignora el hecho de que también hay casos de asociaciones de parte-todo-con partes no compartibles donde las partes pueden separarse del todo y sobrevivir a la destrucción del todo.
En el documento de especificación de UML, la definición del término "composición" siempre ha implicado partes que no se pueden compartir, pero no ha quedado claro cuál es la característica definitoria de la "composición" y qué es simplemente una característica opcional. Incluso en la nueva versión (a partir de 2015), UML 2.5, después de un intento de mejorar la definición del término "composición", sigue siendo ambiguo y no proporciona ninguna orientación sobre cómo modelar asociaciones parte-todo-con Partes compartibles en las que las partes pueden desprenderse del todo y sobrevivir a la destrucción del mismo, en contraposición al caso en el que las partes no pueden separarse y se destruyen junto con el todo. Ellos dicen
Si se elimina un objeto compuesto, todas sus instancias de parte que son objetos se eliminan con él.
Pero al mismo tiempo también dicen
Un objeto parcial se puede eliminar de un objeto compuesto antes de que se elimine el objeto compuesto y, por lo tanto, no se puede eliminar como parte del objeto compuesto.
Esta confusión apunta a un carácter incompleto de la definición de UML, que no tiene en cuenta las dependencias del ciclo de vida entre componentes y compuestos. Por lo tanto, es importante comprender cómo se puede mejorar la definición de UML mediante la introducción de un estereotipo de UML para composiciones << inseparables >> donde los componentes no pueden separarse de su compuesto y, por lo tanto, deben destruirse cada vez que se destruye su compuesto.
1) Composición
Como ha explicado Martin Fowler , el problema principal para caracterizar la composición es que "un objeto sólo puede ser parte de una relación de composición". Esto también se explica en la excelente publicación de blog UML Composition vs Aggregation vs Association de Geert Bellekens. Además de esta característica definitoria de una composición (tener partes exclusivas o no compartibles ), una composición también puede tener una dependencia del ciclo de vida entre el compuesto y sus componentes. De hecho, existen dos tipos de tales dependencias:
- Siempre que un componente deba estar siempre unido a un compuesto, o, en otras palabras, cuando tenga un compuesto obligatorio , expresado por la multiplicidad "exactamente uno" en el lado compuesto de la línea de composición, entonces debe reutilizarse en (o se vuelve a unir a) otro compuesto, o se destruye, cuando se destruye su compuesto actual. Esto se ejemplifica con la composición entre
Person
y Heart
, que se muestra en el diagrama siguiente. Un corazón se destruye o se trasplanta a otra persona, cuando su dueño ha muerto.
- Siempre que un componente no pueda separarse de su compuesto, o, en otras palabras, cuando sea inseparable , entonces, y solo entonces, el componente debe ser destruido, cuando su compuesto se destruya. Un ejemplo de tal composición con partes inseparables es la composición entre
Person
y Brain
.
En resumen, las dependencias del ciclo de vida solo se aplican a casos específicos de composición, pero no en general, por lo que no son una característica definitoria.
La especificación UML establece: "Una parte se puede eliminar de una instancia compuesta antes de que se elimine la instancia compuesta y, por lo tanto, no se puede eliminar como parte de la instancia compuesta". En el ejemplo de una composición Car
- Engine
, como se muestra en el siguiente diagrama, es evidente que el motor puede separarse del automóvil antes de que se destruya, en cuyo caso el motor no se destruye y se puede reutilizar. Esto está implícito en la multiplicidad cero o uno en el lado compuesto de la línea de composición.
La multiplicidad del extremo de asociación de una composición en el lado compuesto es 1 o 0..1, dependiendo del hecho de si los componentes tienen un compuesto obligatorio (deben estar unidos a un compuesto) o no. Si los componentes son inseparables , esto implica que tienen un compuesto obligatorio.
2) Agregación
Una agregación es otra forma especial de asociación con el significado pretendido de una relación entre parte y todo, donde las partes de un todo pueden compartirse con otros todos. Por ejemplo, podemos modelar una agregación entre las clases DegreeProgram
y Course
, como se muestra en el siguiente diagrama, dado que un curso es parte de un programa de grado y un curso se puede compartir entre dos o más programas de grado (por ejemplo, un título de ingeniería podría compartir un C curso de programación con título en informática).
Sin embargo, el concepto de una agregación con partes compartibles no significa mucho, en realidad, por lo que no tiene ninguna implicación en la implementación y, por lo tanto, muchos desarrolladores prefieren no usar el diamante blanco en sus diagramas de clases, sino simplemente modelar una asociación simple. en lugar. La especificación UML dice: "La semántica precisa de la agregación compartida varía según el área de aplicación y el modelador".
La multiplicidad del extremo de asociación de una agregación en el lado completo puede ser cualquier número (*) porque una parte puede pertenecer o ser compartida entre cualquier número de totalidades.