Clean Code Reimagined
Patterns for Practical Elegance
Engineering Resilience, Not Just Readability
By Nigel Dsouza
Preface
This revised edition of my original clean code article is inspired by public feedback and valuable peer review comments. I've rewritten the examples with proper formatting, replaced controversial patterns with widely accepted standards, added new Node.js examples for consistency, and infused the piece with unique metaphors and analogies for a more personal and creative take.
Abstract
Clean code is not a style choice — it's a mindset. In this piece, we explore the art and science of writing elegant, maintainable, and scalable code across two ecosystems: Node.js and Java. With side-by-side examples, real-world analogies, and updated best practices, this is your practical guide to sustainable software development.
Introduction
Bad code works — until it doesn't. Then it explodes, silently and catastrophically.
Clean code, on the other hand, builds systems that bend, adapt, and scale. Whether you're deploying microservices with Spring Boot or writing event-driven logic in Node.js, the goal remains: make your code understandable, predictable, and extendable.
In this updated cookbook, we dissect common code patterns and refactor them into clean, professional-grade examples — with clarity, real-world relevance, and a few new flavors.
1️⃣ Name Things Like They Matter
Bad naming is like seasoning the wrong dish. It ruins the experience.
Poor Practice (Java)
// Calculate interest
double i = p * r * t / 100;
✅ Clean Practice (Java)
double simpleInterest = principal * rate * time / 100;
Poor Practice (Node.js)
// Get user info
const u = getUser();
✅ Clean Practice (Node.js)
const currentUser = getUser();
Principle: Write names so good they make comments unnecessary.
2️⃣ Keep Functions Focused (and Use Logic That Fits)
A function should do one thing. Not validate, throw, persist, and email in a single breath.
Poor Practice (Node.js)
function handleSignup(req) {
validate(req); // throws error directly
saveToDB(req); // vague naming
sendWelcomeEmail(req.email);
}
✅ Clean Practice (Node.js)
function handleSignup(req) {
if (!validateInput(req)) return respondWithError();
saveUserData(req);
sendWelcomeEmail(req.email);
}
Clarification: Throwing inside validation is valid in some contexts, but here we handle errors explicitly for clarity. Also renamed saveToDB()
to saveUserData()
for semantic alignment.
3️⃣ Don't Repeat Decisions — Let the Code Decide
If-else chains are code's version of micromanagement.
✅ Node.js DRY Logic
const roleActions = {
ADMIN: () => showAdminPanel(),
EDITOR: () => showEditorPanel(),
};
if (roleActions[user.role]) {
roleActions[user.role]();
}
✅ Java DRY Logic
Map<String, Runnable> roleActions = Map.of(
"ADMIN", this::showAdminPanel,
"EDITOR", this::showEditorPanel
);
roleActions.get(user.getRole()).run();
Principle: Replace conditionals with data-driven logic for maintainability.
4️⃣ Format Like You Mean It
Readable code is respectful code. It's the difference between chaos and cohesion.
✅ Modern Async (Node.js)
async function fetchData(url) {
try {
const response = await fetch(url);
return await response.json();
} catch (err) {
logError(err);
}
}
Fix: Replaced .then/.catch
chaining with async/await
. Used proper indentation for ESLint-like readability.
5️⃣ Make Side Effects Obvious
State mutation is powerful — and dangerous if hidden.
Poor Practice (Node.js)
function updateScore(user) {
user.score += 10;
return user;
}
✅ Clean Practice (Node.js)
function updateScore(user) {
return {
...user,
score: user.score + 10,
};
}
✅ Clean Practice (Java)
User updatedUser = new User(user.getName(), user.getScore() + 10);
Principle: Favor immutability — pure functions are safer and scale better.
6️⃣ Logs Are Not Noise — They're Breadcrumbs
Logs should be meaningful, human-readable, and context-rich.
✅ Node.js Logging
console.log(`[UserModule] Profile updated: ${user.id}`);
✅ Java Logging
LOGGER.info("User {} updated profile successfully.", user.getId());
Principle: Great logs are the difference between debugging and despair.
Comparative Summary
Descriptive Variables
- Node.js:
const totalCost = price * quantity;
- Java:
double simpleInterest = ...;
Single Responsibility
- Node.js:
createUser()
focuses on persistence only
- Java: Split logic into
UserService
, NotificationService
DRY Logic
- Node.js: Role-handler maps
- Java: Functional maps with
Runnable
Immutability
- Node.js: Object spread syntax
- Java: New object creation with constructor
Structured Logging
- Node.js: Template tags with module context
- Java: SLF4J-style parameterized messages
Conclusion
Clean code isn't an aesthetic — it's a practice. When we write functions that teach, logs that narrate, and systems that think ahead, we build software that lasts.
The next time you're writing a feature, think like a chef: prep your variables, follow a clean recipe, and taste before you ship.
Because clean code isn't just for you — it's for everyone who comes after you.
About the Author
Nigel Dsouza is a Principal Software Engineer and Tech Lead at Fidelity Investments. He designs and builds automated cloud-native systems, blending the precision of Java with the agility of Node.js. He believes great code isn’t just functional — it’s expressive, efficient, and empathetic.