Callers use long dotted access paths to walk through one object to reach another's data — `order.customer.address.street` exposes every intermediate boundary.
Callers ask the closest object for what they want; the object delegates internally without exposing its collaborators.
Before the refactoring
const street = order.customer.address.street;
After the refactoring
// inside Order: customerStreet() { return this.customer.address.street; }const street = order.customerStreet();
Every link in the chain is a coupling point; renaming any intermediate field breaks every caller; consumers depend on the full graph shape.
Adds a passthrough method on the parent for every delegated operation — only worth it for operations that are repeated across consumers.
Encapsulation tightens; intermediate objects can change shape without breaking callers.
Wrapping every dotted access in a passthrough — including chains used only once where the wrapper adds cost without removing real coupling.