Clean Code vs. Code-Smells

Introduction

As an aspiring software engineer constantly learning new coding concepts and strategies, my coding practices have been improving both directly and subconsciously. Now that I am reaching the end of my journey as only a student of computer science, It’s important to recognize that mastering clean code principles and eliminating code smells are vital in building maintainable codebases .

Clean Code

After reading an article from FreeCodeCamp.org on writing clean code, one thing I want to start doing more often is called the Single Responsibility Principle (SRP) which states that every class or module should only have one responsibility.

Here are some examples found on FreeCodeCamp.org:

// Example 1: Withouth SRP
function processOrder(order) {
  // validate order
  if (order.items.length === 0) {
    console.log("Error: Order has no items");
    return;
  }

  // calculate total
  let total = 0;
  order.items.forEach(item => {
    total += item.price * item.quantity;
  });

  // apply discounts
  if (order.customer === "vip") {
    total *= 0.9;
  }

  // save order
  const db = new Database();
  db.connect();
  db.saveOrder(order, total);
}

The above code block shows processOrder which isn’t utilizing SRP. It handles several functions, which makes it hard to understand. Furthermore a change to one function may change the others which makes it hard to maintain.

// Example 2: With SRP
class OrderProcessor {
  constructor(order) {
    this.order = order;
  }

  validate() {
    if (this.order.items.length === 0) {
      console.log("Error: Order has no items");
      return false;
    }
    return true;
  }

  calculateTotal() {
    let total = 0;
    this.order.items.forEach(item => {
      total += item.price * item.quantity;
    });
    return total;
  }

  applyDiscounts(total) {
    if (this.order.customer === "vip") {
      total *= 0.9;
    }
    return total;
  }
}

class OrderSaver {
  constructor(order, total) {
    this.order = order;
    this.total = total;
  }

  save() {
    const db = new Database();
    db.connect();
    db.saveOrder(this.order, this.total);
  }
}

const order = new Order();
const processor = new OrderProcessor(order);

if (processor.validate()) {
  const total = processor.calculateTotal();
  const totalWithDiscounts = processor.applyDiscounts(total);
  const saver = new OrderSaver(order, totalWithDiscounts);
  saver.save();
}

This above code shows the same method but this time utilizing SRP. The processOrder has been split up into multiple classes, OrderProcessor and OrderSaver which gives each classes its own functionality. This makes the code easier to understand and maintain.

Code-Smells

A code smell, which are indicators in code that reveal that there may be a problem in the design of the code, is something I am unashamed to admit that I am guilty of. The first step in correcting a problem is to admit you have one, and there is one thing that I wish to avoid doing in the future to make my code less smelly.

Code duplication an easy issue to create, as it can be so easy to just ignore it because its functional, but failure to correct these kinds of problems early can make the codebase unmaintainable. By performing refactoring, one can remove duplicated code.

Here are some examples of what I mean that I found on Medium.com:


The above code block shows two functions can contain duplicate code, one function to calculate the area of a rectangle, and the other to calculate the perimeter. While they do serve to distinct purposes, the code is so incredibly similar they don’t need to be in two different functions.

The code block above shows the refactored version, which creates a function that utilizes the logic of the area function, and simply reuses it for the perimeter. This solves the issue with duplicate logic and improves maintainability.

Sources

https://www.freecodecamp.org/news/how-to-write-clean-code/?utm_source=chatgpt.com

https://leonardoherdy.medium.com/clean-code-does-code-smell-part-1-7cf593f1e502

Leave a Reply

Your email address will not be published. Required fields are marked *