Return to site

🎯🧬 MESSAGE CHAINS: THE HIDDEN COUPLING SMELL

November 10, 2025

🔸 TL;DR

▪️ Message chains leak internals and create fragile coupling.

▪️ Fix by hiding delegates, moving/extracting behavior, or introducing facades/services.

▪️ Follow the Law of Demeter and Tell, Don’t Ask for cleaner, resilient code. ✅( see: https://blog.vvauban.com/blog/law-of-demeter-lod-don-t-talk-to-strangers )

🔸 WHAT IT IS

▪️ A message chain is a call that calls a call that calls a call… (a.b().c().d()), exposing deep object structure.

▪️ You’re reaching through one object to touch another → tight coupling, brittle code. 🧩

🔸 WHY IT’S BAD

▪️ Coupling → bad: A tiny change deep inside breaks callers far away.

▪️ Law of Demeter 🚷: “Only talk to your immediate friends.” Chains talk to friends-of-friends.

▪️ Readability ↓ and mocking/tests get messy (lots of stubs).

▪️ Tell, don’t ask: Chains ask for internals instead of telling an object to do work.

🔸 CODE SMELL EXAMPLE

// Message chain

var city = order.getCustomer().getAddress().getCity();

🔸 BETTER OPTIONS

▪️ Hide Delegate (inverse of Middle Man):

// Order hides the delegate

public String getCustomerCity() { return customer.getAddress().getCity(); }

// Callers

var city = order.getCustomerCity();

▪️ Extract/Move Function to the rightful owner:

// Tell the object to do it

order.shipToCustomerCity();

▪️ Introduce Facade / Service to wrap traversal and provide intent-revealing API.

▪️ Use DTO/Assembler to flatten read models for queries (CQRS-friendly).

▪️ Sequence of Temps ➡️ Avoid if it’s just chaining getters:

// Not better if it just exposes internals step by step

var c = order.getCustomer();

var a = c.getAddress();

var city = a.getCity();

▪️ Guard Rails: Prefer interfaces that expose behavior, not structure; review chains in PRs; add static analysis rules (e.g., detect get().get() patterns).

🔸 TAKEAWAYS

▪️ Spot it: Look for . repeated 3+ times.

▪️ Name intent: Replace chains with intent-revealing methods.

▪️ Own the behavior: Put logic where the data lives.

▪️ Refactor safely: Add tests, then Hide Delegate / Move Function / Facade.

#CleanCode #Refactoring #LawOfDemeter #TellDontAsk #Java #Spring #SoftwareDesign #CodeSmell #Architecture #OOP #TDD #Craftsmanship

Go further with Java certification:

Java👇

Spring👇

SpringBook👇