Me ha costado mucho entender la diferencia entre composición y agregación en UML. ¿Alguien puede ofrecerme una buena comparación y contraste entre ellos? También me encantaría aprender a reconocer la diferencia entre ellos en el código y / o ver un ejemplo breve de software / código.
Editar: Parte de la razón por la que pregunto es debido a una actividad de documentación inversa que estamos haciendo en el trabajo. Hemos escrito el código, pero tenemos que volver atrás y crear diagramas de clases para el código. Simplemente nos gustaría capturar las asociaciones correctamente.
Respuestas:
La distinción entre agregación y composición depende del contexto.
Tome el ejemplo del automóvil mencionado en otra respuesta: sí, es cierto que el escape de un automóvil puede sostenerse "por sí solo", por lo que puede no estar en composición con un automóvil, pero depende de la aplicación. Si crea una aplicación que realmente tenga que lidiar con escapes de automóviles independientes (¿una aplicación de administración de talleres de automóviles?), La agregación sería su elección. Pero si se trata de un juego de carreras simple y el escape del automóvil solo sirve como parte de un automóvil, bueno, la composición sería bastante buena.
Tablero de ajedrez? El mismo problema. Una pieza de ajedrez no existe sin un tablero de ajedrez solo en determinadas aplicaciones. En otros (como el de un fabricante de juguetes), una pieza de ajedrez seguramente no se puede componer en un tablero de ajedrez.
Las cosas empeoran aún más al intentar asignar la composición / agregación a su lenguaje de programación favorito. En algunos idiomas, la diferencia puede ser más fácil de notar ("por referencia" versus "por valor", cuando las cosas son simples) pero en otros puede que no exista en absoluto.
¿Y un último consejo? No pierda demasiado tiempo en este tema. No vale la pena. La distinción es poco útil en la práctica (incluso si tiene una "composición" completamente clara, es posible que desee implementarla como una agregación debido a razones técnicas, por ejemplo, almacenamiento en caché).
fuente
Como una regla de oro:
En composición (Persona, Corazón, Mano), los "subobjetos" (Corazón, Mano) serán destruidos tan pronto como Persona sea destruida.
En conjunto (ciudad, árbol, automóvil), los "subobjetos" (árbol, automóvil) NO serán destruidos cuando se destruya la ciudad.
La conclusión es que la composición enfatiza la existencia mutua y, en conjunto, esta propiedad NO es necesaria.
fuente
La composición y la agregación son tipos de asociaciones. Están muy relacionados y en términos de programación no parece haber mucha diferencia entre los dos. Intentaré explicar la diferencia entre estos dos mediante ejemplos de código java.
Agregación : El objeto existe fuera del otro, se crea fuera, por lo que se pasa como argumento (por ejemplo) al constructor. Ej: Gente - coche. El automóvil se crea en un contexto diferente y luego se convierte en propiedad de una persona.
Composición : El objeto solo existe, o solo tiene sentido dentro del otro, como parte del otro. Ej: Gente - corazón. No creas un corazón y luego se lo pasas a una persona. En cambio, el corazón se crea cuando se crea el humano.
Explicado aquí con un ejemplo Diferencia entre agregación y composición
fuente
La composición implica que los objetos secundarios comparten una vida útil con los principales. La agregación no lo hace. Por ejemplo, un tablero de ajedrez se compone de cuadrados de ajedrez; los cuadrados de ajedrez no existen realmente sin el tablero. Sin embargo, un automóvil es una agregación de partes: un escape de automóvil sigue siendo un escape de automóvil si no es parte de un automóvil en ese momento.
fuente
El ejemplo que aprendí fue de dedos a la mano. Tu mano está compuesta por dedos. Los posee. Si la mano muere, los dedos mueren. No puedes "agregar" dedos. No puede simplemente tomar dedos adicionales y unirlos y separarlos de su mano a voluntad.
El valor aquí, desde el punto de vista del diseño, a menudo está relacionado con la vida útil del objeto, como dijo otro cartel. Digamos que tiene un cliente y ellos tienen una cuenta. Esa Cuenta es un objeto "compuesto" del cliente (al menos, en la mayoría de los contextos que se me ocurren). Si elimina al Cliente, la Cuenta no tiene valor por sí misma, por lo que también se eliminará. Lo contrario suele ser cierto en la creación de objetos. Dado que una cuenta solo tiene significado en el contexto de un cliente, la creación de la cuenta se produciría como parte de la creación del cliente (o, si lo hace con pereza, sería parte de alguna transacción del cliente).
Es útil en diseño pensar en qué objetos poseen (componen) otros objetos en comparación con los que solo hacen referencia (agregan) a otros objetos. Puede ayudar a determinar dónde recae la responsabilidad de la creación / limpieza / actualización de objetos.
En cuanto al código, a menudo es difícil saberlo. Casi todo en el código es una referencia de objeto, por lo que puede que no sea obvio si el objeto al que se hace referencia está compuesto (propiedad) o agregado.
fuente
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
Pero al mismo tiempo también dicen
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:
Person
yHeart
, que se muestra en el diagrama siguiente. Un corazón se destruye o se trasplanta a otra persona, cuando su dueño ha muerto.Person
yBrain
.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
yCourse
, 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.
fuente
En términos de código, la composición generalmente sugiere que el objeto contenedor es responsable de crear instancias del componente *, y el objeto contenedor contiene las únicas referencias duraderas a él. Entonces, si el objeto principal se elimina de la referencia y se recolecta la basura, también lo hará el secundario.
entonces este código ...
sugiere que LineItem es un componente de Order - LineItems no existe fuera de su orden contenedor. Pero los objetos Item no se construyen en el orden, se pasan según sea necesario y continúan existiendo, incluso si la tienda no tiene pedidos. por lo que están asociados, en lugar de componentes.
* nb, el contenedor es responsable de instanciar el componente, pero es posible que en realidad no llame a new ... () en sí mismo, siendo java, ¡generalmente hay una fábrica o dos para pasar primero!
fuente
Las ilustraciones conceptuales proporcionadas en otras respuestas son útiles, pero me gustaría compartir otro punto que he encontrado útil.
He aprovechado un poco UML para la generación de código, para el código fuente o DDL para la base de datos relacional. Allí, he usado la composición para indicar que una tabla tiene una clave externa no anulable (en la base de datos) y un objeto "padre" (ya menudo "final") no anulable, en mi código. Utilizo la agregación cuando pretendo que un registro u objeto pueda existir como "huérfano", no adjunto a ningún objeto principal, o que sea "adoptado" por un objeto principal diferente.
En otras palabras, he usado la notación de composición como una forma abreviada para implicar algunas restricciones adicionales que podrían ser necesarias al escribir código para el modelo.
fuente
El ejemplo que me gusta: Composición: El agua es parte de un estanque. (El estanque es una composición de agua). Agregación: el estanque tiene patos y peces (el estanque agrega patos y peces)
Como puede ver, he puesto en negrita "parte de" y "tiene", ya que estas 2 frases normalmente pueden indicar qué tipo de conexión existe entre las clases.
Pero como han señalado otros, muchas veces si la conexión es una composición o una agregación depende de la aplicación.
fuente
Es muy difícil hacer una diferencia entre la relación agregada y la relación compuesta, pero voy a tomar algunos ejemplos, tenemos una casa y habitaciones, aquí tenemos una relación compuesta, la habitación es parte de la casa y comenzó la vida de la habitación. con la vida de la casa y Will terminará cuando la vida de la casa termine, la habitación es parte de la casa, hablamos de composición, como país y capital, libro y páginas. Para el ejemplo de relación agregada, tome el equipo y los jugadores, el jugador puede existir sin equipo y el equipo es un grupo de jugadores, y la vida del jugador puede comenzar antes que la vida del equipo, si hablamos de programación, podemos crear jugadores y después crearemos el equipo, pero para la composición no, creamos habitaciones dentro de la casa. Composición ----> compuesto | componiendo. Agregación -------> grupo | elemento
fuente
Establezcamos los términos. La agregación es un metatérmino en el estándar UML y significa AMBAS composición y agregación compartida, simplemente denominada compartida . A menudo se denomina incorrectamente "agregación". Es MALO, porque la composición también es una agregación. Según tengo entendido, te refieres a "compartido".
Más allá del estándar UML:
Entonces, la asociación de Universidad a cátedras es una composición, porque la cátedra no existe fuera de la Universidad (en mi humilde opinión)
Es decir, todas las demás asociaciones se pueden dibujar como agregaciones compartidas, si solo está siguiendo algunos principios suyos o de alguien más. También mira aquí .
fuente
Considere partes del cuerpo humano como riñón, hígado, cerebro. Si intentamos mapear el concepto de composición y agregación aquí, sería como:
Antes del advenimiento del trasplante de partes del cuerpo como el de los riñones y el hígado, estas dos partes del cuerpo estaban en composición con el cuerpo humano y no pueden existir aisladas con el cuerpo humano.
Pero después del advenimiento del trasplante de partes del cuerpo, se pueden trasplantar en otro cuerpo humano, por lo que estas partes están en agregación con el cuerpo humano, ya que ahora es posible su existencia aislada con el cuerpo humano.
fuente