The real cost of unnecessary complexity
Why over-engineering is often the fastest path to project failure.
Author: Danilo FernandoPublished on February 10, 2025
Complexity on compound interest
Complexity is the biggest cause of technical bankruptcy I’ve seen up close. Every “just in case” abstraction is an implicit contract with the future — and the future always cashes in.
“The only thing more expensive than solving the wrong problem is solving the right one with three layers of indirection nobody asked for.”
Warning signs
- Abstractions that exist for a single use case.
- In-house frameworks for problems the ecosystem already solves.
- “Let’s make it pluggable” before two plugs exist.
- Dynamic config for something that changes once a year.
- Mapping layers between identical objects.
Practical heuristic
Before creating an abstraction, ask:
- Are there two real consumers today?
- Is the cost of extracting later prohibitive?
- Does the behaviour actually vary, or just the name?
If the answer is “no” to all three, inline is the right answer.
A concrete example
// Before — flexibility nobody asked for
public interface UserNotifier {
void notify(User user, NotificationPayload payload);
}
public class EmailUserNotifier implements UserNotifier { /* ... */ }
// After — the system only sends email, period
public class EmailService {
public void sendWelcome(User user) { /* ... */ }
}
When the second channel appears, you extract the interface in five minutes, green tests and a clear head about what actually changes.
Summary
Start from real pain, not theoretical elegance. Clean Code is about maintenance cost, not interfaces per megabyte.
#clean-architecture #technical-decisions