SOLID & DESIGN PRINCIPLES / OBJECT DESIGN BRIEF

Law of Demeter

The Law of Demeter (principle of least knowledge) says a method should only talk to its immediate friends: its own fields, its parameters, objects it creates, and itself, not to objects returned by those friends.

IntermediatePhase 02 / Topic 8 of 8ResponsibilitiesCollaborationsExtensibility
01

Overview

The Law of Demeter (principle of least knowledge) says a method should only talk to its immediate friends: its own fields, its parameters, objects it creates, and itself, not to objects returned by those friends. Code like order.getCustomer().getAddress().getCity() reaches through a chain of objects and couples the caller to the structure of all of them.

Following Demeter means asking objects to do things (order.shippingCity()) rather than navigating their internals. It reduces coupling and makes refactoring easier. It is a guideline, not an absolute: fluent builders and data transfer objects are acceptable chains.

Paying at a shop

The cashier asks you for payment; you hand over money. The cashier does not reach into your pocket, open your wallet, and pull out the cash. You decide how to pay.

02

When to use it

  • Code has long chains of getters (train wrecks).
  • Changing one class's internal structure breaks distant callers.
  • Mocks in tests return mocks that return mocks.
03

Where it shows up in interviews

Train-wreck refactoring

Recognize it when: a.getB().getC().doSomething().

  • Refactor order shipping logic
  • Design a car with engine and components
04

Where it is used in real software

Tell, don't ask

Martin Fowler and the Pragmatic Programmers promote telling objects what to do, which follows Demeter naturally.

Mock-heavy tests

Deep mock chains in Mockito tests are a common symptom of Demeter violations.

Fluent APIs

Builders and streams chain calls on the same or new objects, which is an accepted exception.

05

Key terms

Immediate friends
this, parameters, fields, and locally created objects.
Train wreck
Chained getters reaching deep into object graphs.
Tell, don't ask
Ask objects to perform behavior instead of extracting data.
Delegation method
A method that forwards a request to a collaborator.
06

How it works, step by step

  1. 1
    Spot the chain

    order.getCustomer().getWallet().debit(x).

  2. 2
    Ask what the caller really wants

    To charge the customer.

  3. 3
    Add behavior to the nearest object

    order.chargeCustomer(x) or customer.pay(x).

  4. 4
    Let each object delegate one level

    Customer delegates to its wallet.

  5. 5
    Avoid adding dozens of trivial wrappers

    Rethink responsibilities if delegation explodes.

07

Reaching vs telling

A delivery service needs the city for an order

Step 1 / 2
CodeCaller depends onIf Address moves inside Profile
order.getCustomer().getAddress().getCity()Order, Customer, AddressCaller breaks
order.shippingCity()Order onlyOnly Order changes

NOWCode: order.getCustomer().getAddress().getCity() | Caller depends on: Order, Customer, Address | If Address moves inside Profile: Caller breaks

Each object knows about its neighbors, not the whole graph.

08

Implementation

class Wallet {  constructor(private balanceCents: number) {}  debit(cents: number) {    if (cents > this.balanceCents) throw new Error("Insufficient funds");    this.balanceCents -= cents;  }} class Customer {  constructor(private wallet: Wallet) {}  pay(cents: number) { this.wallet.debit(cents); } // delegates one level} class Order {  constructor(private customer: Customer, private totalCents: number) {}  checkout() { this.customer.pay(this.totalCents); }} // Violation would be: order.getCustomer().getWallet().debit(total)new Order(new Customer(new Wallet(10_000)), 2_500).checkout();
09

Complexity and performance

Coupling per caller1 object

vs whole chain.

Extra methodsA few delegations

Keep them meaningful.

10

Trade-offs

Wrapper explosion

Strictly following Demeter can add many forwarding methods; if so, the responsibility may belong elsewhere.

Data structures are exempt

Navigating plain data (DTOs, JSON, records) is fine; the law targets objects with behavior.

11

Variants and related techniques

Fluent interfaces

Chaining on the same builder object is not a violation.

Facade

Hides a subsystem's graph behind one object.

12

Common mistakes

  • Treating it as 'count the dots'.

    Fix: The concern is coupling to structure, not syntax.

  • Returning internals so callers can act.

    Fix: Move the action into the owner.

13

Interview questions

What is a train-wreck call and why is it bad?

A chain like a.getB().getC().doX(). The caller becomes coupled to the internal structure of B and C, so refactoring any of them breaks it; it also usually means behavior lives in the wrong place.

Are builders a Law of Demeter violation?

No. Each builder call returns the same builder or a new value, so the caller only talks to one object it created.

14

Practice problems

ProblemDifficultyWhat it trains
Refactor three train-wreck callsEasyTell, don't ask.
Model a car so drivers never touch engine partsMediumDelegation.