Pregunta Agregación versus composición [cerrado]


Me ha costado entender la diferencia entre composición y agregación en UML. ¿Puede alguien por favor 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 pequeño ejemplo 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 regresar y crear diagramas de clase para el código. Simplemente nos gustaría capturar las asociaciones correctamente.


73
2018-04-09 16:10


origen


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 "solo", por lo que puede no estar en la composición de un automóvil, pero depende de la aplicación. Si construyes una aplicación que realmente tiene que lidiar con escapes de autos independientes (¿una aplicación de gestión de tiendas de autos?), La agregación sería tu elección. Pero si este es 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 ciertas aplicaciones. En otros (como el de un fabricante de juguetes), una pieza de ajedrez seguramente no puede ser compuesta en un tablero de ajedrez.

Las cosas empeoran cuando tratas de asignar composición / agregación a tu lenguaje de programación favorito. En algunos idiomas, la diferencia puede ser más fácil de notar ("por referencia" vs. "por valor", cuando las cosas son simples), pero en otros puede no existir en absoluto.

Y una última palabra de consejo? No pierdas demasiado tiempo en este tema. No vale la pena. La distinción apenas es ú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, el almacenamiento en caché).


80
2018-04-09 16:37



Como una regla de oro: enter image description here

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), "objetos secundarios" (Corazón, Mano) serán destruidos tan pronto como la Persona sea destruida.

En agregación (Ciudad, Árbol, Coche) "Sub objetos" (Árbol, Coche) NO serán destruidos cuando la Ciudad sea destruida.

La conclusión es que la composición acentúa la existencia mutua y, en conjunto, esta propiedad NO es necesaria.


83
2018-02-05 21:25



La composición implica que los objetos secundarios comparten una vida útil con el padre. La agregación no. Por ejemplo, un tablero de ajedrez se compone de cuadrados de ajedrez: los cuadros de ajedrez no existen realmente sin el tablero. Sin embargo, un automóvil es una agregación de partes: el escape de un automóvil sigue siendo el escape de un automóvil si no es parte de un automóvil en ese momento.


36
2018-04-09 16:15



La composición y la agregación son tipos de asociaciones. Están estrechamente relacionados y en términos de programación no parece mucha diferencia. Voy a tratar de explicar la diferencia entre estos dos ejemplos de código java

Agregación: el objeto existe fuera del otro, se crea fuera, por lo que se pasa como un argumento (por ejemplo) al construtor. Ej .: Gente - automóvil. 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 pasa a una persona.

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


34
2017-09-23 20:12



El ejemplo que aprendí fue con los dedos en la mano. Tu mano está compuesta de dedos. Los posee. Si la mano muere, los dedos mueren. No puedes "agregar" dedos. No puedes simplemente agarrar dedos extra y unirlos y separarlos de tu mano a voluntad.

El valor aquí, desde el punto de vista del diseño, a menudo se relaciona con la duración del objeto, como dijo otro cartel. Digamos que tienes 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 ocurre). Si elimina al Cliente, la Cuenta no tiene ningún valor por sí misma, por lo que también se eliminará. Lo contrario a menudo es cierto en la creación de objetos. Debido a que una Cuenta solo tiene significado en el contexto de un Cliente, la creación de la Cuenta ocurriría como parte de la creación del Cliente (o, si lo hace de forma perezosa, sería parte de alguna transacción del Cliente).

En el diseño, es útil pensar qué objetos poseen (componer) otros objetos frente a los que simplemente hacen referencia (agregan) otros objetos. Puede ayudar a determinar dónde recae la responsabilidad de la creación / limpieza / actualizaciones de objetos.

En cuanto al código, a menudo es difícil de decir. La mayoría de todo en el código es una referencia de objeto, por lo que puede no ser obvio si el objeto al que se hace referencia es compuesto (propiedad) o agregado.


18
2018-04-09 16:51



Es sorprendente cuánta confusión existe sobre la distinción entre parte-todo-asociación conceptos agregación y composición. El problema principal 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 este punto de vista ignora el hecho de que también hay casos de asociaciones de parte-todo con partes no compartibles donde las partes pueden separarse y sobrevivir a la destrucción del todo.

En el documento de especificación UML, la definición del término "composición" siempre ha implicado partes no compartibles, pero no ha quedado claro cuál es la característica definitoria de "composición", y qué es meramente 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 ambigua y no proporciona ninguna guía sobre cómo modelar las asociaciones de parte a conjunto con las no partes compartibles donde las partes pueden separarse y sobrevivir a la destrucción del todo, en oposición al caso en que las partes no se pueden separar 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 borrará como parte del objeto compuesto.

Esta confusión apunta a una definición incompleta de UML, que no tiene en cuenta las dependencias del ciclo de vida entre los componentes y los compuestos. Por lo tanto, es importante comprender cómo se puede mejorar la definición UML mediante la introducción de un estereotipo UML para <<inseparable>> composiciones donde los componentes no se pueden separar de su compuesto, y, por lo tanto, tienen que destruirse siempre que se destruya su compuesto.

1) Composición

Como Martin Fowler ha explicado, el principal problema para caracterizar la composición es que "un objeto solo puede ser parte de una relación de composición". Esto también se explica en la excelente publicación de blog Composición UML vs Agregación vs Asociación por Geert Bellekens. Además de esta característica definitoria de una composición (tener exclusivo, o no compartible, partes), una composición también puede venir con una dependencia del ciclo de vida entre el compuesto y sus componentes. De hecho, hay dos tipos de tales dependencias:

  1. Siempre que un componente siempre debe estar adjunto a un compuesto, o, en otras palabras, cuando tiene un compuesto obligatorio, según lo expresado por la multiplicidad "exactamente una" en el lado compuesto de la línea de composición, entonces debe ser reutilizado (o reintegrado) a otro compuesto, o destruido, cuando se destruye su material compuesto actual. Esto se ejemplifica por la composición entre Persony Heart, que se muestra en el diagrama a continuación. Un corazón es destruido o trasplantado a otra persona, cuando su dueño ha muerto.
  2. Siempre que un componente no se puede separar de su compuesto, o, en otras palabras, cuando es inseparable, entonces, y solo entonces, el componente debe ser destruido, cuando se destruye su compuesto. Un ejemplo de tal composición con partes inseparables es la composición entre Persony Brain.

enter image description here

En resumen, las dependencias del ciclo de vida solo se aplican a casos específicos de composición, pero no en general, por lo tanto, 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 elimine como parte de la instancia compuesta". En el ejemplo de un Car-Engine composición, como se muestra en el siguiente diagrama, es evidente que el motor puede separarse del automóvil antes de que se destruya el automóvil, en cuyo caso el motor no se destruye y puede reutilizarse. Esto está implícito en el cero o uno multiplicidad en el lado compuesto de la línea de composición.

enter image description here

los multiplicidad del extremo de asociación de una composición en el lado compuesto es 1 o 0..1, dependiendo del hecho si los componentes tienen un compuesto obligatorio (deben estar unidos a un compuesto) o no. Si los componentes son inseparable, 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 parte-todo, donde las partes de un todo se pueden compartir con otras totalidades. Por ejemplo, podemos modelar una agregación entre las clases DegreeProgram y Course, como se muestra en el siguiente diagrama, ya que un curso es parte de un programa de grado y un curso puede compartirse entre dos o más programas de grado (por ejemplo, un título de ingeniería podría compartir un curso de programación C con un grado de informática).

enter image description here

Sin embargo, el concepto de 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 utilizar el diamante blanco en sus diagramas de clases, sino simplemente modelar una asociación simple. La especificación de UML dice: "La semántica precisa de la agregación compartida varía según el área de aplicación y el modelador".

los multiplicidad del extremo de asociación de una agregación en todo el lado puede ser cualquier número (*) porque una parte puede pertenecer a, o compartido entre, cualquier cantidad de totalidades.


13
2018-01-11 16:00



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 de larga vida al mismo. Por lo tanto, si el objeto principal se redirige y se recoge basura, también lo hará el niño.

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 tienen existencia fuera de su orden de contenido. Pero los objetos Item no están construidos en el orden: se transfieren según sea necesario y continúan existiendo, incluso si el taller no tiene pedidos. entonces están asociados, en lugar de componentes.

* n.b. el contenedor es responsable para instanciar el componente, pero puede que en realidad no llame a new ... () en sí mismo. ¡Esto es java, por lo general hay una fábrica o dos para pasar primero!


6
2018-04-09 17:07



Las ilustraciones conceptuales proporcionadas en otras respuestas son útiles, pero me gustaría compartir otro punto que encontré útil.

He obtenido algunos beneficios de 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 foránea que no admite nulos (en la base de datos) y un objeto "padre" (y a menudo "final") que no admite nulos en mi código. Uso la agregación cuando intento que un registro u objeto pueda existir como "huérfano", no asociado a ningún objeto principal, o para ser "adoptado" por un objeto principal diferente.

En otras palabras, he utilizado la notación de composición como una forma abreviada de implicar algunas restricciones adicionales que podrían ser necesarias al escribir el código para el modelo.


0
2018-04-09 18:22