Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Association
LLD

Association

Understand general relationships between independent classes and how they interact.

The Problem It Names

Objects in a real domain must reference each other — an Order needs its Customer. The design questions are subtler than “should there be a field”: which side holds the reference? how many on each end? and does knowledge flow one way or both? Association is the umbrella term for these structural “knows-a” links — the weakest and most common relationship type.

Direction

 UNI-DIRECTIONAL                          BI-DIRECTIONAL

 ┌───────┐  order.customer   ┌──────────┐  ┌───────┐ orders   customer
 │ Order │ ────────────────► │ Customer │  │ Order │◄────────►│ refs
 └───────┘                   └──────────┘  └───────┘◄────────►└────────┘
 Customer never points back;                Each can navigate to the other;
 Customer code works with no                both fields must be kept in sync
 Order existing at all.                     by every mutating call site.

Left: only Order knows Customer. Navigation is one-way; Customer compiles without importing Order at all. Right: both hold fields, enabling customer.getOrders() — purchased at the price of maintaining two structures that must always agree. A forgotten sync (order.setCustomer(x) without adding to x.orders) silently corrupts navigation from the other side.

Java Mechanics

class Order {                       // uni-directional
    private final Customer customer;
    Order(Customer c) { this.customer = c; }
}

// bi-directional requires paired updates:
class Customer {
    private final List<Order> orders = new ArrayList<>();
    void addOrder(Order o) { orders.add(o); }
}
class Order {
    private Customer customer;
    void attachTo(Customer c) {
        if (this.customer != null) this.customer.removeOrder(this);
        this.customer = c;
        c.addOrder(this);           // both sides updated together
    }
}

Multiplicity

UML annotates each end: 1, 0..1, *, 1..* — “an Order has exactly 1 Customer; a Customer has 0..* Orders.” Zero-capable multiplicities drive null-handling and empty-collection decisions in code; interviewers probe them deliberately (“can a user have zero orders?” decides whether getOrders() may return empty vs throw).

Trade-offs

Uni-directionalBi-directional
NavigationOne way onlyBoth ways
Sync costNoneEvery mutation touches two sides
CouplingLower (one import direction)Higher (circular imports likely)
Memory retentionReferenced object kept alive by holderBoth retained while either lives
Serialization/GC hazardsMinimalCycles need special handling

Real-World Usage

  • Default to uni-directional; add the reverse pointer when a proven query need exists.
  • ORMs formalize this: JPA @ManyToOne (owning side) + @OneToMany(mappedBy=...) — the annotation exists precisely because bidirectional sync is error-prone.
  • Bidirectional memory retention matters for caches: a cache entry holding a back-reference to its owner prevents collection of both.

Interview Signals

  • Stating direction explicitly on the diagram (“orders know customers, not vice versa”) reads as deliberate design.
  • The experienced answer to “why not always bidirectional?”: sync burden + coupling + retention — three concrete costs, not taste.

My Private Notes

Notes are auto-saved locally to this device.