The six relationships and multiplicity
Part of the free Low-Level Design course on LogicWiz, in the chapter: Class diagrams you can draw in five minutes. The class-diagram exercises run in the app.
Week 3, Day 4: Six lines, six meanings
"You used the same arrow everywhere. So the order owns the customer? If I delete an order, does the customer disappear too?"
Priya, pointing at Arjun's diagram
Lines carry the design
Arjun's diagram had good boxes. Every line between them was the same plain arrow. Priya asked what each arrow meant, and he said "they are connected". That answer loses marks.
In an interview the lines carry the design. They say who holds whom, who owns whom, and what happens when an object is deleted. UML has six relationships you need. Two are about using another class, two are about ownership, and two are about type.
Keeps it, or uses it briefly
Association means one class keeps a reference to another in a field. An Order keeps the Customer who placed it. Draw a solid line with an open arrowhead pointing at the class being referred to.
Dependency means one class uses another only for a short time: as a method parameter, a local variable or a return value. It does not keep it. Draw a dashed line with an open arrowhead.
public class Order {
private final Customer customer; // association: kept in a field
public Order(Customer customer) { this.customer = customer; }
}
public class InvoicePrinter {
public String print(Order order) { // dependency: used, not kept
return "Invoice: " + order;
}
}
A quick test: if the other class appears as a field, it is association. If it appears only inside a method, it is dependency.
Owns, or groups: composition and aggregation
Both of these describe a whole made of parts. The difference is lifetime: how long the part lives compared with the whole.
Composition is strong ownership. The whole creates the part, the part belongs to only that whole, and the part has no meaning once the whole is gone. An Order and its OrderItem lines are an example. Delete the order and its lines go with it. Draw a solid line with a filled diamond at the whole.
Aggregation is a weaker grouping. The part can exist on its own and can move between wholes. A DeliveryZone groups Rider objects. Close a zone and the riders still exist; they move to another zone. Draw a solid line with a hollow diamond at the whole.
classDiagram
Order "1" *-- "1..*" OrderItem : contains
Order "*" --> "1" Customer : placedBy
DeliveryZone "1" o-- "*" Rider : groups
InvoicePrinter ..> Order : prints
A candidate in a mock said, "In Java both are fields, so the diamond is decoration." The field can look the same. The difference is in who creates the part and who else may hold it. With composition, Order creates its OrderItem objects inside its own methods and never shares them. With aggregation, the zone receives riders that were created somewhere else. Interviewers ask about this because it decides deletion, copying and sharing later in the design.
⚠️ Warning: When you are unsure, ask "if the whole is deleted, should the part be deleted too?" Yes means composition. No means aggregation. If neither feels right, use plain association.
Is a, or can do: inheritance and realisation
Inheritance, also called generalisation, means a class extends a parent class. SmsNotification is a Notification. Draw a solid line with a hollow triangle at the parent.
Realisation means a class implements an interface. UpiPayment implements PaymentMethod. Draw a dashed line with a hollow triangle at the interface.
classDiagram
class PaymentMethod {
<<interface>>
+pay(amountPaise: long) Receipt
}
PaymentMethod <|.. UpiPayment
PaymentMethod <|.. CardPayment
Notification <|-- SmsNotification
Here are all six side by side.
| Relationship | Line | Marker | Read it as |
|---|---|---|---|
| Association | solid | open arrow at the held class | keeps a reference |
| Dependency | dashed | open arrow at the used class | uses it for a moment |
| Aggregation | solid | hollow diamond at the whole | groups; the part lives on |
| Composition | solid | filled diamond at the whole | owns; the part dies with it |
| Inheritance | solid | hollow triangle at the parent | is a |
| Realisation | dashed | hollow triangle at the interface | implements |
Multiplicity: how many
Multiplicity says how many objects can sit at each end of a line. You write it near the end it describes.
1means exactly one.0..1means none or one.*(also written0..*) means any number, including none.1..*means at least one.
Read each number as "how many of this class, for one object at the other end". The line Order "*" --> "1" Customer says each order has exactly one customer, and one customer can have many orders. The line Order "1" *-- "1..*" OrderItem says each order has at least one item, and each item belongs to exactly one order. An order and its rider would be 0..1 at the rider end. A rider is assigned only after packing, and a cancelled order never gets one.
Multiplicity turns into code. A 1 usually becomes a required constructor parameter. A 0..1 becomes a field that may be empty. A * becomes a List or a Map.
Try it: fix Arjun's arrows
The starter is Arjun's diagram. Most lines are plain associations, and one composition makes the order own its customer. Click each line and change it to the right relationship type. Then add multiplicities at both ends of the order lines.
📌 Summary: Association keeps a reference; dependency uses one briefly. Composition (filled diamond) owns parts that die with the whole; aggregation (hollow diamond) groups parts that live on. Inheritance and realisation end in hollow triangles.
What Arjun learns next
Arjun can now read and draw any class diagram. Next week he learns how to judge whether a design is good, starting with three of the SOLID principles: single responsibility, open/closed and Liskov substitution.
Check your understanding
- When SwiftKart deletes an order, its OrderItem lines must go too. Which relationship fits?
- A DeliveryZone is closed and its riders move to another zone. How should the zone-to-rider line be drawn?
- ReportService has `export(List<Order> orders)` and uses the orders only inside that method. What line goes from ReportService to Order?
- A rider is assigned to an order only after packing, and a cancelled order never gets one. What multiplicity goes at the rider end?
- A dashed line with a hollow triangle runs from UpiPayment to PaymentMethod. What does it say?