Law of Demeter
debt(d5/e5/b5/t5)
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.
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.
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.
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.
Also Known As
TL;DR
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
Why It Matters
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
// Violation — traverses the object graph (train wreck)
$city = $order->getCustomer()->getAddress()->getCity()->getName();
// 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