Agrégation versus composition [fermé]

89

J'ai eu du mal à comprendre la différence entre la composition et l'agrégation dans UML. Quelqu'un peut-il s'il vous plaît me proposer une bonne comparaison et un contraste entre eux? J'aimerais aussi apprendre à reconnaître la différence entre eux dans le code et / ou voir un court exemple de logiciel / code.

Edit: Une partie de la raison pour laquelle je demande est à cause d'une activité de documentation inversée que nous faisons au travail. Nous avons écrit le code, mais nous devons revenir en arrière et créer des diagrammes de classes pour le code. Nous aimerions simplement capturer correctement les associations.

Dave
la source
Veuillez consulter un exemple basé sur le code sur: stackoverflow.com/questions/731802/…
Almir Campos
UML 2.5 a clarifié la différence. Voir l'encadré p. 110. Je vote donc pour rouvrir cela.
qwerty_so
Non, UML 2.5 n'a pas clarifié la définition de la composition, il est plutôt resté ambigu à ce sujet, car ils disent également "Un objet pièce peut être supprimé d'un objet composite avant que l'objet composite ne soit supprimé, et donc ne pas être supprimé dans le cadre de l'objet composite. " Voir ma réponse ci-dessous ( stackoverflow.com/questions/734891/… ) où j'ai essayé de clarifier le sens de la composition. Veuillez augmenter ma réponse pour montrer que dans SO, la bonne réponse l'emporte à la fin :-) [ou rejeter toutes les réponses incorrectes]
Gerd Wagner

Réponses:

90

La distinction entre agrégation et composition dépend du contexte.

Prenons l'exemple de voiture mentionné dans une autre réponse - oui, il est vrai qu'un échappement de voiture peut se tenir "tout seul" et peut donc ne pas être en composition avec une voiture - mais cela dépend de l'application. Si vous créez une application qui doit réellement gérer des échappements de voiture autonomes (une application de gestion de magasin automobile?), L'agrégation serait votre choix. Mais s'il s'agit d'un simple jeu de course et que l'échappement de la voiture ne fait partie que d'une voiture - eh bien, la composition serait très bonne.

Échiquier? Même problème. Une pièce d'échecs n'existe pas sans échiquier uniquement dans certaines applications. Dans d'autres (comme celui d'un fabricant de jouets), une pièce d'échecs ne peut certainement pas être composée en un échiquier.

Les choses empirent encore lorsque vous essayez de mapper la composition / agrégation à votre langage de programmation préféré. Dans certaines langues, la différence peut être plus facile à remarquer ("par référence" vs "par valeur", quand les choses sont simples) mais dans d'autres, elle peut ne pas exister du tout.

Et un dernier conseil? Ne perdez pas trop de temps sur cette question. Cela n'en vaut pas la peine. La distinction n'est guère utile en pratique (même si vous avez une «composition» parfaitement claire, vous pouvez toujours vouloir l'implémenter sous forme d'agrégation pour des raisons techniques - par exemple, la mise en cache).

Hexagone
la source
1
J'ai dit carré d'échecs plutôt que pièce d'échecs, mais tous les points valides.
David M
2
Je suis définitivement en désaccord avec l'état d'esprit «ça n'en vaut pas la peine». Si vous ne réfléchissez pas à qui «possède» un objet et est responsable de sa durée de vie, vous obtiendrez un code très merdique lié à l'objet CRUD, en particulier le nettoyage, avec des pointeurs Null qui volent alors que les hiérarchies d'objets sont laissées dans de mauvais états.
Chris Kessel
9
Oui, vous ne devriez pas perdre trop de temps sur cette question: UML est un langage OOA / OOD; L'agrégation / composition est généralement une décision qu'il vaut mieux différer jusqu'à la POO. Si vous essayez de mettre trop de détails dans vos modèles UML, vous risquez une paralysie de l'analyse.
chimpanzé
13
+1 pour "ne perdez pas trop de temps là-dessus". C'est ce que j'avais besoin d'entendre!
Ronnie
8
"ne perdez pas trop de temps là-dessus" Pourquoi les intervieweurs ne comprennent-ils pas cela?
titogeo
96

En règle générale: entrez la description de l'image ici

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

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

Dans la composition (Personne, Coeur, Main), les "sous-objets" (Coeur, Main) seront détruits dès que Personne sera détruite.

Dans l'ensemble (ville, arbre, voiture), les "sous-objets" (arbre, voiture) ne seront PAS détruits lorsque la ville sera détruite.

L'essentiel est que la composition met l'accent sur l'existence mutuelle, et dans l'agrégation, cette propriété n'est PAS requise.

nxhoaf
la source
1
existence mutuelle, bon B-)
jxramos
Apprécier votre effort. Une très bonne explication et tout profane peut comprendre cela.
Ravindran Kanniah
Explication la plus simple et la meilleure que j'ai rencontrée.
Akash Raghav
meilleure explication :)
Xiabili
UML 2.5 a clarifié la différence. Voir l'encadré p. 110. Donc, votre réponse est tout simplement fausse maintenant,
qwerty_so
51

La composition et l'agrégation sont des types d'associations. Ils sont très étroitement liés et, en termes de programmation, il ne semble pas y avoir beaucoup de différence entre les deux. Je vais essayer d'expliquer la différence entre ces deux exemples de code java

Agrégation : L'objet existe en dehors de l'autre, est créé à l'extérieur, il est donc passé en argument (par exemple) au constructeur. Ex: Gens - voiture. La voiture est créée dans un contexte différent et devient alors une propriété individuelle.

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

Composition : L'objet n'existe, ou n'a de sens qu'à l'intérieur de l'autre, en tant que partie de l'autre. Ex: les gens - le cœur. Vous ne créez pas un cœur pour ensuite le transmettre à une personne. Au lieu de cela, le cœur est créé lorsque l'humain est créé.

// 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”);
  }
}

Expliqué ici avec un exemple Différence entre agrégation et composition

vsingh
la source
5
Une des meilleures réponses à ce jour. Neat :)
Rohit Singh
6
Le meilleur exemple de code Java pour montrer quand un objet peut exister avec (composition) ou sans (agrégation) d'autres objets.
Michał Dobi Dobrzański
s'il vous plaît, je veux savoir est-ce que nous devrions utiliser final pour la composition ou pas?
Outreagous ONE
36

La composition implique que les objets enfants partagent une durée de vie avec le parent. L'agrégation ne le fait pas. Par exemple, un échiquier est composé de cases d'échecs - les cases d'échecs n'existent pas vraiment sans l'échiquier. Cependant, une voiture est une agrégation de pièces - un échappement de voiture est toujours un échappement de voiture s'il ne fait pas partie d'une voiture à ce moment-là.

David M
la source
18

L'exemple que j'ai appris était les doigts à la main. Votre main est composée de doigts. Il les possède. Si la main meurt, les doigts meurent. Vous ne pouvez pas "agréger" les doigts. Vous ne pouvez pas simplement attraper des doigts supplémentaires et les attacher et les détacher de votre main à volonté.

La valeur ici, du point de vue de la conception, est souvent liée à la durée de vie de l'objet, comme l'a dit une autre affiche. Supposons que vous ayez un client et qu'il ait un compte. Ce compte est un objet «composé» du client (du moins, dans la plupart des contextes auxquels je peux penser). Si vous supprimez le client, le compte n'a aucune valeur en soi, il sera donc également supprimé. L'inverse est souvent vrai lors de la création d'objets. Étant donné qu'un compte n'a de sens que dans le contexte d'un client, la création d'un compte se produit dans le cadre de la création du client (ou, si vous le faites paresseusement, cela ferait partie d'une transaction client).

Il est utile dans la conception de réfléchir à quels objets possèdent (composent) d'autres objets par rapport à ceux qui font simplement référence (agrégent) d'autres objets. Cela peut aider à déterminer la responsabilité de la création / du nettoyage / des mises à jour des objets.

En ce qui concerne le code, c'est souvent difficile à dire. La plupart de tout dans le code est une référence d'objet, il n'est donc pas évident que l'objet référencé soit composé (possédé) ou agrégé.

Chris Kessel
la source
15

Il est étonnant de voir à quel point il existe une certaine confusion sur la distinction entre l' agrégation et la composition des concepts partie-tout - association . Le problème principal est le malentendu généralisé (même parmi les développeurs de logiciels experts et parmi les auteurs d'UML) selon lequel le concept de composition implique une dépendance du cycle de vie entre le tout et ses parties, de sorte que les parties ne peuvent exister sans le tout. Mais ce point de vue ignore le fait qu'il existe également des cas d'associations partie-tout avec des parties non partageables où les parties peuvent se détacher et survivre à la destruction du tout.

Dans le document de spécification UML, la définition du terme «composition» a toujours impliqué des parties non partageables, mais il n'a pas été clair quelle est la caractéristique de définition de «composition», et ce qui est simplement une caractéristique facultative. Même dans la nouvelle version (à partir de 2015), UML 2.5, après une tentative d'améliorer la définition du terme «composition», il reste encore ambigu et ne fournit aucune indication sur la façon de modéliser des associations partie-tout avec des non- parties partageables où les parties peuvent être détachées de, et survivre à la destruction du tout, par opposition au cas où les parties ne peuvent pas être détachées et sont détruites avec le tout. Ils disent

Si un objet composite est supprimé, toutes ses instances de pièce qui sont des objets sont supprimées avec lui.

Mais en même temps, ils disent aussi

Un objet pièce peut être supprimé d'un objet composite avant que l'objet composite ne soit supprimé, et donc ne pas être supprimé en tant que partie de l'objet composite.

Cette confusion indique une incomplétude de la définition UML, qui ne tient pas compte des dépendances de cycle de vie entre les composants et les composites. Il est donc important de comprendre comment la définition UML peut être améliorée en introduisant un stéréotype UML pour les compositions « inséparables » où les composants ne peuvent pas être détachés de leur composite, et doivent donc être détruits chaque fois que leur composite est détruit.

1) Composition

Comme l' a expliqué Martin Fowler , le principal problème pour caractériser la composition est qu '"un objet ne peut faire partie que d'une seule relation de composition". Ceci est également expliqué dans l'excellent article de blog UML Composition vs Aggregation vs Association par Geert Bellekens. En plus de cette caractéristique déterminante d'une composition (avoir des parties exclusives ou non partageables ), une composition peut également présenter une dépendance du cycle de vie entre le composite et ses composants. En fait, il existe deux types de telles dépendances:

  1. Chaque fois qu'un composant doit toujours être attaché à un composite, ou, en d'autres termes, lorsqu'il a un composite obligatoire , tel qu'exprimé par la multiplicité "exactement un" du côté composite de la ligne de composition, il doit être soit réutilisé dans (ou ré-attaché à) un autre composite, ou détruit, lorsque son composite actuel est détruit. Ceci est illustré par la composition entre Personet Heart, illustrée dans le diagramme ci-dessous. Un cœur est détruit ou transplanté à une autre personne, lorsque son propriétaire est décédé.
  2. Chaque fois qu'un composant ne peut pas être détaché de son composite, ou, en d'autres termes, lorsqu'il est inséparable , alors, et alors seulement, le composant doit être détruit, lorsque son composite est détruit. Un exemple d'une telle composition avec des parties inséparables est la composition entre Personet Brain.

entrez la description de l'image ici

En résumé, les dépendances du cycle de vie ne s'appliquent qu'à des cas spécifiques de composition, mais pas en général, elles ne constituent donc pas une caractéristique déterminante.

La spécification UML stipule: "Une pièce peut être supprimée d'une instance composite avant que l'instance composite ne soit supprimée, et donc ne pas être supprimée comme partie de l'instance composite." Dans l'exemple d'une Car- Enginecomposition, comme le montre le schéma suivant, il est clair que le moteur peut être détaché de la voiture avant que la voiture ne soit détruite, auquel cas le moteur n'est pas détruit et peut être réutilisé. Ceci est impliqué par la multiplicité zéro ou une du côté composite de la ligne de composition.

entrez la description de l'image ici

La multiplicité de l'extrémité d'association d'une composition côté composite est de 1 ou 0..1, selon le fait que les composants ont un composite obligatoire (doivent être attachés à un composite) ou non. Si les composants sont inséparables , cela implique qu'ils ont un composite obligatoire.

2) Agrégation

Une agrégation est une autre forme particulière d'association avec la signification voulue d'une relation partie-tout, où les parties d'un tout peuvent être partagées avec d'autres ensembles. Par exemple, nous pouvons modéliser une agrégation entre les classes DegreeProgramet Course, comme le montre le diagramme suivant, puisqu'un cours fait partie d'un programme d'études et qu'un cours peut être partagé entre deux ou plusieurs programmes d'études (par exemple, un diplôme d'ingénieur pourrait partager un C cours de programmation avec un diplôme en informatique).

entrez la description de l'image ici

Cependant, le concept d'une agrégation avec des parties partageables ne signifie pas grand-chose, vraiment, donc il n'a aucune implication sur l'implémentation et de nombreux développeurs préfèrent donc ne pas utiliser le diamant blanc dans leurs diagrammes de classes, mais simplement modéliser une association simple au lieu. La spécification UML dit: "La sémantique précise de l'agrégation partagée varie selon le domaine d'application et le modeleur".

La multiplicité de l'extrémité d'association d'une agrégation sur le côté entier peut être n'importe quel nombre (*) parce qu'une partie peut appartenir à, ou partagée entre, n'importe quel nombre de touts.

Gerd Wagner
la source
2
La composition n'est pas strictement liée au cycle de vie, mais dans la plupart des problèmes du monde réel, le cycle de vie est le principal facteur de motivation pour savoir si vous composez ou agrégez. J'ai couvert ma réponse, en disant que le cycle de vie est "souvent" lié plutôt que toujours lié. Il est bon de noter que le cycle de vie n'est pas nécessaire, mais affirmer que la vue est un "problème principal" et que ce n'est pas le cas (avec une belle police en gras) me semble inutile et empêche de signaler les considérations pratiques d'utilisation.
Chris Kessel
Je suis fortement en désaccord. Les considérations relatives au cycle de vie ne peuvent pas être un "facteur de motivation principal pour savoir si vous composez ou agrégerez", car vous les avez dans de nombreux cas d'associations indépendamment du fait qu'elles représentent un type de relation partielle (agrégation ou composition). Chaque fois qu'une association a une fin avec une multiplicité de borne inférieure supérieure à 0, correspondant à une propriété de référence obligatoire, vous obtenez une dépendance de cycle de vie.
Gerd Wagner
9

En termes de code, la composition suggère généralement que l'objet conteneur est responsable de la création des instances du composant *, et que l'objet conteneur contient les seules références de longue durée à celui-ci. Donc, si l'objet parent est dé-référencé et récupéré, l'enfant le sera également.

donc ce code ...

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

suggère que LineItem est un composant de Order - Les LineItems n'ont pas d'existence en dehors de leur ordre contenant. Mais les objets Item ne sont pas construits dans l'ordre - ils sont transmis selon les besoins et continuent d'exister, même si la boutique n'a pas de commandes. ils sont donc associés, plutôt que des composants.

* nb le conteneur est responsable de l'instanciation du composant, mais il peut ne pas appeler new ... () lui-même - ceci étant java, il y a généralement une usine ou deux à parcourir en premier!

Chris May
la source
0

Les illustrations conceptuelles fournies dans d'autres réponses sont utiles, mais j'aimerais partager un autre point que j'ai trouvé utile.

J'ai obtenu un certain kilométrage grâce à UML pour la génération de code, pour le code source ou DDL pour la base de données relationnelle. Là, j'ai utilisé la composition pour indiquer qu'une table a une clé étrangère non nullable (dans la base de données), et un objet "parent" non nullable (et souvent "final"), dans mon code. J'utilise l'agrégation là où j'ai l'intention qu'un enregistrement ou un objet puisse exister en tant qu '"orphelin", non attaché à un objet parent, ou être "adopté" par un autre objet parent.

En d'autres termes, j'ai utilisé la notation de composition comme un raccourci pour impliquer des contraintes supplémentaires qui pourraient être nécessaires lors de l'écriture de code pour le modèle.

Erickson
la source
0

L'exemple que j'aime bien: Composition: L' eau fait partie d' un étang. (L'étang est une composition d'eau.) Agrégation: l' étang contient des canards et des poissons (l'étang regroupe des canards et des poissons)

Comme vous pouvez le voir, j'ai mis en gras «part-of» et «has», car ces 2 phrases peuvent généralement indiquer le type de connexion existant entre les classes.

Mais comme d'autres l'ont souligné, le fait que la connexion soit une composition ou une agrégation dépend souvent de l'application.

Raj Rao
la source
Mais une partie de et a des termes confond parfois. Par exemple, une classe Person "a" nom, donc montre que Person a une relation d'agrégation avec nom. En fait, c'est une relation de composition. Pourquoi? Lorsque l'objet Person détruit, le nom devrait l'être également. Et le terme "le nom fait partie de la personne" ne semble pas naturel.
Asif Shahzad
0

C'est tellement difficile de faire une différence entre la relation agrégée et la relation composite, mais je vais prendre quelques exemples, nous avons une maison et des pièces, ici nous avons une relation composite, la pièce fait partie de la maison et la vie de la pièce a commencé avec la vie à la maison et la finira quand la vie à la maison sera terminée, la pièce fait partie de la maison, nous parlons de composition, comme le pays et la capitale, le livre et les pages. Pour un exemple de relation agrégée, prenons l'équipe et les joueurs, le joueur peut exister sans équipe, et l'équipe est un groupe de joueurs, et la vie de joueur peut commencer avant la vie d'équipe, si nous parlons de programmation, nous pouvons créer des joueurs et après nous créerons l'équipe, mais pour la composition non, nous créons des pièces à l'intérieur de la maison. Composition ----> composite | composition. Agrégation -------> groupe | élément

lis
la source
0

Fixons les conditions. L'agrégation est un métaterm dans le standard UML, et signifie à la fois composition et agrégation partagée, simplement nommée shared . Trop souvent, il est nommé incorrectement «agrégation». C'est MAUVAIS, car la composition est aussi une agrégation. Si je comprends bien, vous voulez dire «partagé».

Plus loin du standard UML:

composite - Indique que la propriété est agrégée de manière composite, c'est-à-dire que l'objet composite est responsable de l'existence et du stockage des objets composés (parties).

Ainsi, l'association université-cathédras est une composition, car cathedra n'existe pas en dehors de l'université (IMHO)

La sémantique précise de l'agrégation partagée varie selon le domaine d'application et le modélisateur.

C'est-à-dire que toutes les autres associations peuvent être dessinées sous forme d'agrégations partagées, si vous ne suivez que certains de vos principes ou de quelqu'un d'autre. Regardez aussi ici .

Gangnus
la source
0

Considérez les parties du corps humain comme les reins, le foie et le cerveau. Si nous essayons de cartographier le concept de composition et d'agrégation ici, ce serait comme:

Avant l'avènement de la transplantation de parties du corps comme celle des reins et du foie, ces deux parties du corps étaient en composition avec le corps humain et ne peuvent pas exister d'isolement avec le corps humain.

Mais après l'avènement de la transplantation de parties du corps, elles peuvent être transplantées dans un autre corps humain, donc ces parties sont en agrégation avec le corps humain car leur existence en isolement avec le corps humain est maintenant possible.

Azfar Niaz
la source