Concept · Code design
Law of Demeter
Talk only to your immediate collaborators: ask an object to do something instead of reaching through it to its internals.
The Law of Demeter, or principle of least knowledge, came from the Demeter project at Northeastern University in 1987. A method should only call methods on:
- its own object and fields,
- its parameters,
- objects it creates,
and not on objects returned by those calls. Informally: talk to your friends, not to strangers.
The train wreck
Violations look like long chains:
rate := invoice.Customer().Address().Country().TaxRate()This one line knows that invoices have customers, customers have addresses, and addresses have countries with tax rates. Restructure any link — customers with multiple addresses, tax rates by region — and code far away breaks. It also makes testing painful: a fake invoice needs a fake customer with a fake address with a fake country.
The fix is tell, don't ask: move the knowledge to where the data lives, and ask for the result.
rate := invoice.TaxRate() // Invoice asks its customer; Customer knows its addressNow only the types that own the data know how it's structured, and coupling drops.
When it doesn't apply
The law is about objects with behaviour and invariants. It doesn't apply to:
- Plain data structures — a decoded config (
cfg.Database.Pool.MaxConns), a JSON response, a DTO. There's no hidden behaviour to couple to; navigating them is the point. - Fluent interfaces and builders —
query.Where(...).OrderBy(...).Limit(10)returns the same builder each time. - Standard library chains on values you created, like
strings.NewReplacer("a", "b").Replace(s).
Applied mechanically, the law produces dozens of thin delegating methods (invoice.CustomerAddressCountryName()), which is its own smell. Use it as a prompt: when a chain reaches through two or three objects with behaviour, ask whether the caller should be asking a closer object to do the work. See the design principles lesson.