Long chains of method calls create tight coupling and ripple effects. Any change in the chain breaks dependent code.
TL;DR: Send messages only to your direct acquaintances, not their friends.
Problems π
- Tight Coupling
- Broken encapsulation
- Ripple effect
- Fragile, brittle design
- Poor readability
- Difficult testing and maintenance
Solutions π
- Create intermediate methods.
- Apply the Law of Demeter.
- Create higher level messages.
- Add intermediate methods
- Simplify message passing
- Encapsulate collaborations
- Raise abstraction level
Refactorings βοΈ
https://maximilianocontieri.com/refactoring-010-extract-method-object?embedable=true
Context π¬
When you call a.b().c().d(), you create a dependency chain.
Any change inside one link forces you to update all the code that relies on it.
You expose too much internal structure and violate encapsulation.
You also create brittle tests that break after small refactors.
Instead of chaining, introduce clear responsibilities and let each class talk only to its direct acquaintances.
Sample Code π
Wrong π«
class Dog {
constructor(feet) {
this.feet = feet;
}
getFeet() {
return this.feet;
}
}
class Foot {
move() { }
}
feet = [new Foot(), new Foot(), new Foot(), new Foot()];
dog = new Dog(feet);
for (var foot of dog.getFeet()) {
foot.move();
}
// Equivalent to dog.getFeet()[0].move(); dog.getFeet()[1].move() ...
Right π
class Dog {
constructor(feet) {
this.feet = feet;
}
walk() {
// This is encapsulated on how the dog walks
for (var foot of this.feet) {
foot.move();
}
}
}
class Foot {
move() { }
}
feet = [new Foot(), new Foot(), new Foot(), new Foot()];
dog = new Dog(feet);
dog.walk();
Detection π
- Automatic
You can automatically detect this smell using static analysis tools that examine abstract syntax trees (ASTs) and count chained method calls.
Exceptions π
- Builders:
new CarBuilder().withEngine().withWheels().build()
- Fluent APIs: Designed intentionally for chaining
- DSLs: Domain-specific languages where chaining improves readability
Even in these cases, keep chains consistent, predictable, and limited in depth.
Tags π·οΈ
- Complexity
Level π
- Beginner
Why the Bijection Is Important πΊοΈ
In the bijection between your code and the MAPPER, each concept should match a single element.
When you chain too many calls, you blur the map.
Your objects start revealing paths instead of intentions.
That breaks the direct link between the MAPPER and the problem it solves.
AI Generation π€
AI models often create this smell.
They chain method calls to access deep data instead of creating higher-level abstractions.
This happens because the model learns from large codebases that favor shortcuts over clarity.
AI Detection π§²
You can ask an AI to rewrite a chain into a single message or to apply the Law of Demeter.
Simple instructions like "encapsulate this chain" usually work.
Conclusion π
Avoid successive message calls.
Try to hide the intermediate collaborations and create new protocols.
Try Them! π
Remember: AI Assistants make lots of mistakes
Suggested Prompt: correct=break this collaboration chain
Without Proper Instructions |
With Specific Instructions |
---|---|
Relations π©ββ€οΈβπβπ¨
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iv-7sc3w8n
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xi-sit35t1
https://hackernoon.com/code-smell-271-the-hollywood-principle?embedable=true
More Information π
https://refactoring.guru/es/smells/message-chains?embedable=true
https://hackernoon.com/coupling-the-one-and-only-software-designing-problem-9z5a321h?embedable=true
Also Known as πͺͺ
- Message Chains
- Law of Demeter
Credits π
Talk only to your friends, not to strangers.
Karl Lieberherr
https://hackernoon.com/400-thought-provoking-software-engineering-quotes?embedable=true
This article is part of the CodeSmell Series.
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd?embedable=true