Menu

Earn Premium with Referrals

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

See how it works and start inviting friends.

Law of Demeter
LLD

Law of Demeter

Learn how to reduce coupling by limiting the objects and methods a class directly interacts with.

The Problem It Solves

String city = order.getCustomer().getAddress().getCity();

One innocent line, three hidden contracts. This code now knows that Order exposes Customer, Customer exposes Address, Address exposes City. Rename getAddress() → return a Location type? Breaks this line — and every other line like it scattered across the codebase, none of them findable from the class that owns the chain. The Law of Demeter (LoD) formalizes the fix: a method should talk only to its immediate friends — itself, its parameters, its fields, objects it creates — never to strangers reached through friends.

Friend Circle

            ┌──────────────────────────────┐
            │ Method m() in class C        │
            │                              │
            │   this ──────────┐           │
            │   parameters ────┼─ allowed  │
            │   fields' objs ──┤   talks   │
            │   new'd locally ─┘           │
            └──────────┬───────────────────┘

        order.getCustomer().getAddress()...
             ↑ stranger reached THROUGH a friend
               (friend's internals are not your friends)

The rule is about who you may address, not how many dots appear — the dot-count heuristic is a proxy, sometimes wrong.

The Fix — Tell, Don’t Ask

// ask through the chain (violates):
String city = order.getCustomer().getAddress().getCity();

// tell the friend what you want (complies):
String city = order.getShippingCity();     // Order navigates its own data

Order already owns its customer; let it answer. The traversal knowledge collapses into one class that legitimately has it, and internal restructuring stops rippling outward.

Where Chains Are Legitimate

  • Fluent builders / same-module APIs: stream().filter(...).map(...).collect(...) — every link is part of one designed contract returning self/same abstraction. LoD targets coupling to strangers’ internals, not designed chains.
  • Data structures you own: DTO field access within one module boundary.
  • Query-style APIs where intermediate types are stable public contract.

What It Costs

  • Delegating methods accumulate (getShippingCity, getBillingCity, …) — the facade grows.
  • Over-application produces middle-men classes adding indirection without value.

Judgment call: apply hardest at module boundaries, loosely inside cohesive packages.

Real-World Stakes

  • Refactoring safety: LoD-compliant callers survive representation changes silently — the property ORM-heavy codebases desperately need.
  • Test simplification: mocking order.getCustomer().getAddress() means mocking three levels deep; mocking order.getShippingCity() mocks one.

Interview Signals

  • Recognizing a train-wreck line and proposing the tell-dont-ask refactor on sight is standard mid-level signal.
  • The experienced nuance: stating when chains are fine (fluent APIs) before applying the rule mechanically.

My Private Notes

Notes are auto-saved locally to this device.