Ashutosh Kumar

Posted on

# Code Like a Craftsman: Best Practices for Writing Elegant and Maintainable Code

Writing messy code is like joining the dark side of the Force. It may seem tempting at first, with its promises of quick results and powerful abilities. But just like the dark side, it ultimately leads to chaos, confusion, and bugs.

Instead, embrace the Jedi way of clean code. Let go of your attachments to shortcuts and hacks, and focus on the fundamentals. In this article we are gonna look into these fundamentals of clean code that will help you become a Jedi Master of programming. So, get ready to wield your lightsaber of clean code and let's embark on this epic journey together!

## 1. Use Descriptive variable names

Let's face it, choosing variable names can be a daunting task. It's like naming your newborn baby, except you have to name it dozens of times a day. But fear not, young padawan, for there is a simple solution: choose names that make sense!

Think about it, if you saw a variable named "a" in your code, would you have any idea what it represents? It could be an integer, a string, or even a Jedi mind trick for all you know.

``````function calculate(a, b, c, d) {
let x = a * b;
let y = c * d;
let z = x + y;
return z;
}

let result = calculate(2, 3, 4, 5);
console.log(result);
``````

Can you understand the purpose and functionality of this function by looking at the variable names used within it? I hope the answer is 'no', otherwise I'll be afraid that you're leaning towards the dark side of the force and have a strong ability to comprehend poorly named functions.

``````function calculateTotalPrice(numItems, pricePerItem, taxRate, discountRate) {
let subtotal = numItems * pricePerItem;
let tax = subtotal * taxRate;
let discount = subtotal * discountRate;
let total = subtotal + tax - discount;
}

let totalPrice = calculateTotalPrice(5, 10, 0.08, 0.05);
console.log(totalPrice);
``````

In this example, we've used variable names so descriptive that even a confused alien from another galaxy would understand what they represent. And let's not overlook the function name that's so precisely chosen. Even Darth Vader would have a hard time using the Force to obscure the purpose of this function!

## 2. Letting Clarity Prevail Over Comments

Comments should not be the first choice for describing what the code does. They should be used sparingly and only when absolutely necessary. Clean code aims to be self-explanatory, relying on meaningful variable and function names, along with a logical code structure, to convey its purpose. Comments can be helpful for explaining complex algorithms, unusual solutions, potential pitfalls, or interactions with external systems. However, it's crucial to keep comments up to date and ensure they add real value. Clean code speaks for itself, while comments should only supplement understanding when essential.

``````// Perform a binary search on the sorted array
function binarySearch(array, target) {
let left = 0; // Initialize the left boundary of the search range
let right = array.length - 1; // Initialize the right boundary of the search range

// Continue searching while the left boundary is less than or equal to the right boundary
while (left <= right) {
let mid = Math.floor((left + right) / 2); // Calculate the middle index

if (array[mid] === target) {
// If the middle value matches the target, we have found the target value
return mid;
} else if (array[mid] < target) {
// If the middle value is less than the target, the target value is in the right half of the array
left = mid + 1; // Update the left boundary to be mid + 1
} else {
// If the middle value is greater than the target, the target value is in the left half of the array
right = mid - 1; // Update the right boundary to be mid - 1
}
}

// If the target value is not found in the array, return -1
return -1;
}
``````

The existing comments in the code unnecessarily restate information that is already apparent from the code itself. The purpose of variable initialisation and the logic of the binary search algorithm can be easily understood by reading the code without relying on excessive comments.

What if I tell you that this code can look a lot more simple and clean without even changing anything in the code itself? That would be Legen - wait for it - dary. Legendary.

``````// Perform a binary search on the sorted array
function binarySearch(array, target) {
let left = 0;
let right = array.length - 1;

while (left <= right) {
let mid = Math.floor((left + right) / 2);

if (array[mid] === target) {
// Found the target value at index mid
return mid;
} else if (array[mid] < target) {
// Target value is in the right half of the array
left = mid + 1;
} else {
// Target value is in the left half of the array
right = mid - 1;
}
}

return -1;
}
``````

Comments like these help to demystify complex algorithms, making them more approachable and understandable for developers who may encounter the code later on. They provide valuable explanations and guide the reader through intricate logic, making it easier to follow and maintain.

## 3. Embrace the Power of Short and Focused Functions

Remember what Yoda said, "Size matters does not." This is especially true for functions - long, convoluted ones can be like navigating through a dense asteroid field. Instead, break them down into smaller, focused functions with descriptive names. Think of each function like a droid in your own personal Star Wars saga, working together to achieve a common goal.

By using this approach, you'll benefit from greater modularity, reusability, and easier testing. You'll be able to see the code's flow like Obi-Wan saw the Force. So, follow in the footsteps of the Jedi, and let your functions be like lightsabers - short, elegant, and powerful.

## 4. Follow the SOLID Principle

The SOLID principles are a set of five design principles introduced by Robert C. Martin (Uncle Bob) to guide developers in writing clean, modular, and maintainable code. These principles are widely regarded as fundamental in software development.

• SRP (Single Responsibility Principle): A class should have only one reason to change, with a single responsibility.

• OCP (Open-Closed Principle): Software entities should be open for extension but closed for modification, allowing for behavior extension without changing existing code.

• LSP (Liskov Substitution Principle): Subtypes should be substitutable for their base types without altering the correctness of the program.

• ISP (Interface Segregation Principle): Clients should not be forced to depend on interfaces they don't use; interfaces should be specific and tailored to clients' needs.

• DIP (Dependency Inversion Principle): High-level modules should not depend on low-level modules; both should depend on abstractions, promoting loose coupling.

## 5. Unit Tests are the way

Imagine you're a Jedi Knight tasked with constructing a lightsaber. To ensure its reliability and effectiveness, you'd want to test each component individually. In software development, a unit test is like wielding a lightsaber in a controlled environment, examining each piece's functionality.
By writing automated unit tests, you channel your inner Jedi and gain confidence in the behavior of your code. Just as Jedi Knights rely on their lightsabers in battle, you can rely on your unit tests to catch bugs early on, acting as your loyal companions in the ongoing fight against software defects.

In conclusion, embracing the ways of the Jedi and prioritizing clean code leads to software that is as clear as a Jedi's mind. It allows developers to effortlessly understand, modify, and maintain their code, avoiding the dark side of bugs and confusion. Collaboration among developers becomes as harmonious as a Jedi Council, and the Force of clean code saves time and effort in the long run. By following these Jedi principles and honing their skills in writing clean code, developers can become true Jedi Masters, ensuring the quality and success of their development projects. May the clean code be with you!
May the code be with you, always.

Jarrod Roberson • Edited

this is nicely terse, clear and most importantly correct, something you do not see here as much as one would hope.

#2. I would say you could eliminate `// Perform a binary search on the sorted array` comment as well, it is a Tautology.

#4. This one is a slippery slope into religious dogma territory, here is why I say that:

But take the following with the grain of salt that anything can and will be perverted/bastardized and done badly by bad programmers. For consideration, not criticism of your writing. I think SOLID does more harm than good when it is dogma.

SOLID: is tightly coupled with C++/Java/C# "OOP" (as in not actual "Object Oriented" as per the inventor of the term, Alan Kay, would define it), and does not apply to a lot of other languages. Especially the newer ones that are direct reactions to the C++/Java/C#/OOP that become blindly obvious when you work with them long enough and on large enough projects.

SRP: is the one that gets dogmatically drug out of context the most. It gets applied in a way that destroys coherence. High Coherence is the lesson, but everyone stops reading at "Single ..."; because everyone thinks it means "small scope", it causes the opposite; Low Coherence is way worse than if they had never read about it to begin with.

LSP: is not applicable to languages that do not have classes or inheritance.

OSP: is not applicable to languages that do not have inheritance and/or you can not override methods or functions; facades and shadowing do not count they are not inheritance and shadowing is usually a bug and bad if done intentionally.

ISP/DIP: both tend to suffer from the same misunderstanding that SRP does.

SRP/ISP/DIP: would more accurately be promoted as educating people why Loose Couple AND High Cohesion are sides of the same coin and BOTH are required for maintainable design.

I LOVE that you did not use the term "Clean Code" in your title!

I think the term "Clean Code" needs to be retired, it is so tightly coupled with "Uncle Bob" by so many people, most of whom have never actually read the book or watched his talks, they have just trusted the "Clean Code Pastors" to interpret and tell them what to think.

Ashutosh Kumar