Code Like a Craftsman: Best Practices for Writing Elegant and Maintainable Code
Tags: webdev, javascript, programming, beginners
Published: 2023-05-25 13:40:27

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.

```js
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.

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

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.

```js
// 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.*

```js
// 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;
        }
    }

    // Target value not found in the array
    return -1;
}
```
<img src="https://media.giphy.com/media/fSYYG9MSibrmPSuIJ0/giphy.gif"/>

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.

<img src="https://media.giphy.com/media/MQ0YzAeAN03T0tHJip/giphy.gif" />