Association vs Aggregation vs Composition
Every time one class holds a reference to another, it is expressing a relationship. Not all relationships are the same: some objects own what they reference, some share it, some merely know about it. UML gives three names to these shades — association, aggregation, and composition — and the distinction matters because it tells you what happens to the referenced object when the owner goes away.
Each relationship type uses a different UML notation and carries different lifetime semantics.
Association: knows about, but does not own
Association is the loosest link. One class holds a reference to another, but neither creates nor destroys the other. Both objects have independent lifetimes and can exist without each other.
In a university system, a Professor teaches in a Department, but the professor exists before
joining the department and continues to exist if they leave. The department does not create the
professor, and deleting the department does not delete the professor. That independence is the
hallmark of association.
1class Professor:
2 def __init__(self, name: str):
3 self.name = name
4
5class Department:
6 def __init__(self, name: str):
7 self.name = name
8 # Association: Department knows about professors but does not own them.
9 # Professors exist independently and are passed in from outside.
10 self._professors: list[Professor] = []
11
12 def add_professor(self, professor: Professor) -> None:
13 self._professors.append(professor)
Aggregation: has-a, but shared
Aggregation is a stronger claim. The containing object has the referenced objects as a
meaningful part of itself, but they can still be shared with other containers and still outlive
the container. A University contains Department objects — those departments are genuinely part
of the university, not merely known to it. But if the university closes, the departments (and the
people in them) do not simply disappear; they could be transferred or reconstituted elsewhere.
UML marks aggregation with a hollow diamond on the containing end. The key question to ask is: "Can the part exist meaningfully without this container?" If yes, it is aggregation, not composition.