J'ai lu beaucoup de théorie sur les relations d'objet et j'ai encore du mal à comprendre comment l'association et l'agrégation sont séparées du point de vue de l'implémentation . Dans les deux cas, vous aurez l'objet B en tant que membre de données dans l'objet A, où il y est présent en tant que référence (contrairement à la composition où il existe par valeur). Alors, quelle est vraiment la différence entre les deux cas? J'ai lu quelque part que certains gourous de Java considèrent l'agrégation comme un concept uniquement abstrait, un cas «placebo» qui ne peut être distingué (de l'association) du point de vue de l'implémentation / syntaxe, est-ce vrai ou ai-je manqué quelque chose? P >
3 Réponses :
Je suis d'accord que du point de vue de la mise en œuvre, l'association et l'agrégation se ressemblent - comme vous l'avez mentionné, dans les deux cas, l'un des objets est un membre de données dans l'autre.
La façon dont je comprends cela est que la différence d'implémentation dont vous parlez ne se produit pas au niveau de l'objet, mais plutôt au niveau de la conception de l'application:
Si par différence d'implémentation vous comprenez le code lui-même (la façon dont l'objet est placé dans un autre), alors il n'y a aucune différence.
Mais si nous étendons la conversation à la façon dont les objets sont utilisés dans l'application, alors nous devons commencer à regarder si les objets sont autonomes ou non, s'ils peuvent servir une fonction unique et indépendante ou non. C'est à vous de décider s'il s'agit toujours d'une mise en œuvre
Modifier -> explication supplémentaire ajoutée ci-dessous:
le code qui représente l'objet dans la classe (le champ contenant la référence à l'objet)
le code plus large (comment l'objet est utilisé dans d'autres classes ou comment les dépendances entre objets sont représentées)
Ces deux éléments peuvent être compris comme une mise en œuvre , mais à différents niveaux d'abstraction - l'utilisation au sein de la classe est la même pour l ' agrégation et la composition < / strong>, mais la façon dont les relations d'objets sont implémentées dans plusieurs classes serait différente.
Bien entendu, une "différence d'implémentation" concerne "le code lui-même". Ce que vous entendez par votre deuxième élément de liste n'est pas clair. Pourquoi devrait-il y avoir des différences dans l'utilisation sans aucune différence dans le code?
J'ai inclus une explication supplémentaire pour (je l'espère) clarifier mon point.
Pour être correct: le terme d'agrégation UML (auquel vous faites probablement référence) est agrégation composite
. La page 110 de UML 2.5 dit:
composite
- Indique que la propriété est agrégée de manière composite, c'est-à-dire que l'objet composite a la responsabilité de l'existence et du stockage des objets composés (voir la définition des parties en 11.2.3). p>
Si vous voulez dire une agrégation partagée, reportez-vous à la même page p. 110:
shared
- Indique que la propriété a une sémantique d'agrégation partagée. La sémantique précise de l'agrégation partagée varie selon le domaine d'application et le modélisateur.
<↓tl;dr
La différence est assez simple. Un objet composite (agrégé) doit être détruit si l'objet d'agrégation dit au revoir. Un objet associé ne se soucie pas (ou l'objet référent n'essaiera pas de le tuer).
Pour une agrégation partagée: inventez votre propre définition et publiez-la avec son utilisation.
En général, quand les gens disent Agrégation , ils veulent dire partagé AggregationKind. Composite Aggregationkind est communément appelé Composition
@GeertBellekens Shared est encore pire car il n'a pas de sémantique définie. Voir la même p. 110.
@qwerty_so: Votre instruction tl; dr est fausse. La spécification UML dit: "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."
@GerdWagner Je n'ai pas la référence, mais je crois que vous dites la vérité. Cependant, cela ne rend pas ma déclaration erronée. Lorsque l'objet meurt, il doit tuer tous les objets agrégés (encore!). Ceux qui ont été libérés auparavant ne sont pas dans cette liste, ils peuvent donc vivre. Un tl; dr n'est pas l'histoire complète, n'est-ce pas?
@qwerty_so: Ce n'est pas aussi dramatique que de mourir et de tuer. Il s'agit simplement de gestion des dépendances. Dans certains cas (tels que les lignes de commande), les composants peuvent dépendre existentiellement de leurs composites (et doivent ensuite être supprimés / détruits avec eux), et dans d'autres cas (tels que les moteurs de voiture) non.
@GerdWagner Je vois toujours que la discussion sur l'ontologie commence quand il s'agit de ces agrégats. C'est un champ très large. Le fait que les gars de l'OMG aient ajouté ce tableau à la p. 110 d'UML 2.5 me dit simplement qu'ils en sont conscients. Cependant, les gens s'en tiennent toujours à l'ancienne définition (non-) UML.
Il n'y a normalement aucune différence dans l'implémentation d'une agrégation par rapport à une association car leur différence sémantique n'est normalement pas pertinente dans le code d'une application.
Une agrégation est une forme particulière d'association avec la signification voulue d'un partie-tout-relation , 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 DegreeProgram
et 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 cours de programmation C avec un diplôme en informatique).
Modélisation de la relation spéciale entre DegreeProgram
et Course
dans ce way transmet une signification voulue, mais n'a pas à être, et n'est généralement pas, reflétée dans le code d'implémentation, qui peut ressembler à ceci:
class DegreeProgram { private List<Course> courses; ... }