← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Law of Demeter

Code Quality Intermediate
debt(d5/e5/b5/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan and phpmd, both specialist static analysis tools. Detection is marked 'automated: no', meaning even these tools only partially flag the pattern — they can detect long chains but cannot reliably distinguish LoD violations from legitimate fluent interfaces without manual review. This lands squarely at d5.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes identifying train-wreck chains (a.b().c().d()), but correcting them requires adding delegation/wrapper methods on intermediate objects, potentially touching multiple classes. The common_mistakes note about 'adding pass-through methods' and 'wrapping third-party library chains' confirms this is more than a one-line swap — it's a localised but multi-file refactor.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). LoD applies across web, cli, and queue-worker contexts, meaning violations accumulate throughout the codebase. Deep object-graph coupling slows down refactoring whenever any intermediate object changes, creating an ongoing productivity tax. However, it doesn't define the system's entire shape, so b7 would be too high — b5 fits the 'many work streams affected' description.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap (a documented gotcha most devs eventually learn)' (t5). The misconception field explicitly states that developers incorrectly believe LoD prohibits all method chaining, conflating it with fluent interfaces. This is a well-documented and common confusion (also listed as a common_mistake), but it's a known, teachable misconception rather than a catastrophic always-wrong assumption — placing it at t5.

About DEBT scoring →

Also Known As

LoD principle of least knowledge demeter law

TL;DR

A design guideline: a method should only call methods on itself, its parameters, objects it creates, and its direct fields.

Explanation

The Law of Demeter (or Principle of Least Knowledge) states that a unit should have limited knowledge of other units. In practice: don't chain more than one method call on a returned object — $order->getCustomer()->getAddress()->getCity() violates it. Each additional step couples your code to the internal structure of a collaborator. Violations are a symptom of Feature Envy and lead to fragile code that breaks when internal structures change.

Common Misconception

The Law of Demeter prohibits method chaining entirely. It prohibits chaining on different objects to reach deeply nested state. Fluent interfaces on a single object — like a query builder — are not a LoD violation.

Why It Matters

The Law of Demeter limits method calls to immediate collaborators — deep chains like $a->getB()->getC()->doSomething() couple the caller to the entire object graph and break when any link changes.

Common Mistakes

  • Long method chains that traverse multiple object boundaries — each dot is a potential coupling point.
  • Not wrapping third-party library chains behind a local method — your code should not know the library's internal structure.
  • Confusing LoD with fluent interfaces — builder/query patterns on the same object do not violate LoD.
  • Adding pass-through methods just to satisfy LoD without understanding if the relationship between objects should change.

Code Examples

💡 Note
Each dot in a chain is a dependency on internal structure. Wrap the traversal inside the owning class.
✗ Vulnerable
// Violation — traverses the object graph (train wreck)
$city = $order->getCustomer()->getAddress()->getCity()->getName();
✓ Fixed
// Tell, Don't Ask — Order exposes what callers need
class Order {
    public function getCustomerCity(): string {
        return $this->customer->address->city->name;
    }
}

$city = $order->getCustomerCity(); // only one dot from caller's perspective

Added 15 Mar 2026
Edited 22 Mar 2026
Views 90
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 1 ping T 1 ping W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 2 pings S 0 pings S 0 pings M 3 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Scrapy 12 ChatGPT 7 SEMrush 7 Perplexity 6 Ahrefs 6 Bing 6 PetalBot 6 Google 5 Unknown AI 4 Applebot 3 Majestic 2 Sogou 1 Twitter/X 1
crawler 62 crawler_json 3 pre-tracking 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Medium
⚡ Quick Fix
A method should only call methods on: itself, its parameters, objects it creates, and its direct fields — if you see a.b().c().d() that's a train wreck violation
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
$order->getCustomer()->getAddress()->getCity() — method chain crossing multiple object boundaries
Auto-detectable: ✗ No phpstan phpmd
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: High ✗ Manual fix Fix: High Context: Class Tests: Update


✓ schema.org compliant