🎨 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()
tosaveUserData()
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 withasync/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.
Top comments (17)
cleancodecookbook.com/
There's already a clean code cookbook on O'Reilly
Hi Maxi, totally valid point. I’ve since updated the piece and renamed it to Clean Code Reimagined to make it stand apart from O’Reilly’s book. I’ve also added new metaphors, unique formatting, and practical code examples in both Node.js and Java to give it a fresh angle. Appreciate the callout, it pushed me to rethink and improve the whole thing. Thanks.
thanks to you!
I’d strongly recommend revisiting and rewriting this article — here are a few points that might help improve its quality:
Code formatting: It looks like ESLint isn’t being used. The code examples are difficult to read — objects should be split across multiple lines to improve clarity and structure.
Point 2 — terminology and logic: While I agree with the title, I can’t say the same for the content. Throwing exceptions in a validate function is perfectly acceptable and widely used (see Zod for reference). Also, naming a function saveToDB makes sense if you have entity-specific save methods. A normal example is needed.
Missing Node.js example: It’s unclear why Node.js isn’t included in point 3. Adding it would improve consistency and relevance.
Code style and syntax: The code lacks proper linting and indentation, which makes it hard to follow. It would be much more readable if broken into multiple lines. Also, consider using async/await—it’s generally cleaner and more intuitive than chaining .then and .catch.
This article is completely repeated: refactoring.guru/refactoring/what-... , not by example, but content.
Hi Dmitrii,
Thank you so much for the thoughtful feedback and peer reviewing the article, I really appreciated how specific and constructive it was. I’ve taken your points seriously and completely rewrote the article. The code is now properly formatted with multi-line object literals, async/await is used instead of chaining, and I added the missing Node.js example for DRY logic. I also refined the validation logic and renamed vague functions like saveToDB() to make everything clearer. The updated version is called Clean Code Reimagined, would love for you to check it out when you get a chance. Thanks again, your feedback helped make it better.
Clean code by Robert C Martin is an evergreen book with a lot of good practical examples in case you are interested!
Thanks for such a useful article. Keep up the good work!
It is good practice to document code so that it is readable and understandable to others and must become a habit but maybe due to time constraints this practice is lost along the way.
Helpful insight!
Insightful!!
""Because clean code isn't just for you — it's for everyone who comes after you."" I found this the core of the issue and kudos to you for highlighting it.
Coming from the Y2K generation, which was also hugely limited in character capacity amongst others, this rings a clear bell. Code has to live on after its creator and be clear to those who come after.
A little more time and effort in code writing but a quantum jump in code utility going forward. Well said!!
Absolutely agree that clean code is a practice....an ethic....a way of programming life!!
It needs to be in place early in life, else it may never happen!
Great use of examples to illustrate the point!!
Loved this! Nigel takes us through practical rules that make messy code neat and safe—using everyday examples like good names for things, keeping each job focused, and making errors easy to handle. It’s like cooking: pick fresh ingredients (clear names), follow easy steps (small functions), and spice it just right (useful logs). Even someone not deep in programming can see the sense: cleaner code means fewer surprises and less stress later. It’s not just for coders—it’s about building solid foundations that anyone coming after you will appreciate.