Agregación versus composición [cerrado]

89

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.

Dave
fuente
Por favor, consulte un ejemplo basado en código en: stackoverflow.com/questions/731802/…
Almir Campos
UML 2.5 ha aclarado la diferencia. Vea el recuadro en la p. 110. Así que voy a votar para reabrir esto.
qwerty_so
No, UML 2.5 no aclaró la definición de composición, más bien ha permanecido ambiguo al respecto, ya que 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 eliminará como parte de el objeto compuesto ". Vea mi respuesta a continuación ( stackoverflow.com/questions/734891/… ) donde he tratado de aclarar el significado de la composición. Por favor vote mi respuesta para mostrar que en SO, la respuesta correcta gana al final :-) [o rechace todas las respuestas incorrectas]
Gerd Wagner

Respuestas:

90

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é).

Hexágono
fuente
1
Dije cuadrado de ajedrez en lugar de pieza de ajedrez, pero todos puntos válidos.
David M
2
Definitivamente estoy en desacuerdo con la mentalidad de "No vale la pena". Si no piensa en quién "posee" un objeto y es responsable de su vida útil, obtendrá un código muy malo relacionado con el objeto CRUD, en particular la limpieza, con punteros nulos volando mientras las jerarquías de objetos quedan en mal estado.
Chris Kessel
9
Sí, no debería perder demasiado tiempo en este tema: UML es un lenguaje OOA / OOD; La agregación / composición suele ser una decisión que es mejor diferir hasta OOP. Si intenta poner demasiados detalles en sus modelos UML, corre el riesgo de parálisis del análisis.
chimpancé
13
+1 para "no pierdas mucho tiempo en esto". ¡Eso es lo que necesitaba escuchar!
Ronnie
8
"no pierdas mucho tiempo en esto" ¿Por qué los entrevistadores no entienden esto?
titogeo
96

Como una regla de oro: ingrese la descripción de la imagen aquí

class Person {
    private Heart heart;
    private List<Hand> hands;
}

class City {
    private List<Tree> trees;
    private List<Car> cars
}

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.

nxhoaf
fuente
1
existencia mutua, buena B-)
jxramos
Agradecemos su esfuerzo. Una muy buena explicación y cualquier profano puede entender esto.
Ravindran Kanniah
La explicación más simple y mejor que encontré.
Akash Raghav
mejor explicación :)
Xiabili
UML 2.5 ha aclarado la diferencia. Vea el recuadro en la p. 110. Entonces su respuesta es simplemente incorrecta ahora,
qwerty_so
51

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.

// code example for Aggregation:
// reference existing HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer(HttpListener listener, RequestProcessor processor) {
    this.listener = listener;
    this.processor = processor;
  }
}

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.

// code example for composition:
// create own HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer() {
    this.listener = new HttpListener(80);
    this.processor = new RequestProcessor(“/www/root”);
  }
}

Explicado aquí con un ejemplo Diferencia entre agregación y composición

vsingh
fuente
5
Una de las mejores respuestas hasta ahora. Neat :)
Rohit Singh
6
El mejor ejemplo de código Java para mostrar cuándo el objeto puede existir con (composición) o sin (agregación) otros objetos.
Michał Dobi Dobrzański
por favor, quiero saber si debemos usar final para Composición o no.
Outreagous ONE
36

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.

David M
fuente
18

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.

Chris Kessel
fuente
15

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:

  1. 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 Persony 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.
  2. 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 Persony Brain.

ingrese la descripción de la imagen aquí

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.

ingrese la descripción de la imagen aquí

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 DegreeProgramy 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).

ingrese la descripción de la imagen aquí

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.

Gerd Wagner
fuente
2
La composición no está estrictamente relacionada con el ciclo de vida, pero en la mayoría de los problemas del mundo real, el ciclo de vida es un motivador principal de si componer o agregar. Me cubrí en mi respuesta, diciendo que el ciclo de vida está "a menudo" relacionado en lugar de estar siempre relacionado. Es bueno notar que el ciclo de vida no es obligatorio, pero afirmar que la vista es un "problema principal" y que está mal (en una bonita fuente en negrita) me parece inútil y me quita la importancia de señalar las consideraciones prácticas de uso.
Chris Kessel
Estoy totalmente en desacuerdo. Las consideraciones del ciclo de vida no pueden ser un "motivador principal de si compondría o agregaría", ya que las tiene en muchos casos de asociaciones independientemente del hecho de que representen algún tipo de relación de parte y todo (agregación o composición). Siempre que una asociación tenga un final con una multiplicidad de límite inferior mayor que 0, correspondiente a una propiedad de referencia obligatoria, obtendrá una dependencia del ciclo de vida.
Gerd Wagner
9

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 ...

Class Order
   private Collection<LineItem> items;
   ...
   void addOrderLine(Item sku, int quantity){
         items.add(new LineItem(sku, quantity));
   }
}

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!

Chris May
fuente
0

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.

erickson
fuente
0

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.

Raj Rao
fuente
Pero parte de y tiene términos confunde en algún momento. Por ejemplo, una clase Person "tiene" nombre, por lo que se muestra como Person tiene relación de agregación con nombre. De hecho, es una relación de composición. ¿Por qué? Cuando el objeto Person se destruye, también debería hacerlo el nombre. Y el término "el nombre es parte de una persona" no suena natural.
Asif Shahzad
0

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

leer
fuente
0

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:

compuesto: indica que la propiedad se agrega de forma compuesta, es decir, el objeto compuesto tiene la responsabilidad de la existencia y el almacenamiento de los objetos compuestos (partes).

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)

La semántica precisa de la agregación compartida varía según el área de aplicación y el modelador.

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í .

Gangnus
fuente
0

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.

Azfar Niaz
fuente