{ The Rithm Blog. }

3 Patterns for Refactoring Your Code April 12, 2021

When I review code written by people who are relatively new to programming, I find myself often repeating the same advice. There are many patterns we adopt as we learn to code that we have to unlearn or modify once we become more comfortable with the fundamentals. In this post, I'd like to highlight three common patterns I see, and how you can refactor them to write code that is more readable, and often more concise.

Here are three common refactoring strategies you can use when you're revising your code.

1. Return comparisons directly.

Consider the following example:

function isOrange(color) {
  if (color === "orange") {
    return true;
  } else {
    return false;
  }
}

As you can probably tell, this function accepts a color string and returns true if the color is orange. Otherwise, it returns false.

This function will work as expected, but it could be made much shorter. Take a close look at what we're doing: if the expression color === "orange" is true, we return true. if color === "orange" is false, we return false. Either way, we're just returning the value of the comparison itself! This means we can refactor our code to just: 

function isOrange(color) {
  return color === "orange";
}

As a rule of thumb, if you ever find yourself writing an if / else statement where you are just returning true or false, you refactor to just return the condition inside of your if statement. The same goes for ternaries: you never need to write code like return color === "orange" ? true : false.

2. Choose your loop wisely.

Here's another example:

let items = [
  { price: 2.99, description: 'gummy bears' },
  { price: 2.99, description: 'honeydew melon' },
  { price: 3.99, description: 'eggs' }
]

let total = 0;

for (let i = 0; i < items.length; i++) {
  total += items[i].price;
}

As before, this code works just fine. But it would benefit from some refactoring. 

Specifically, the tradition for loop in JavaScript is a bit verbose. We have to store the current index in a variable, and use that to access the array element at that index.

Whenever you are iterating, it's worth asking yourself whether you need the index. Sometimes you do, but often you just need the array element itself. In JavaScript, if you find that you don't actually need the index when looping over an array, you can improve readability by rewriting your loop as a for...of loop instead. Here's how that would look:

let items = [
  { price: 2.99, description: 'gummy bears' },
  { price: 2.99, description: 'honeydew melon' },
  { price: 3.99, description: 'eggs' }
]

let total = 0;
for (let item of items) {
  total += item.price;
}

By selecting the right loop for your problem, you can write code that is both more concise and more readable.

3. Store complex conditions in variables.

Imagine you have an online shop and you want to offer a friends and family discount of 10% on any order over $100. You also have a coupon code of "DISCOUNT10" which will provide a discount of 10%. You write the following function to determine what the discount rate should be on an order:

function getDiscountRate(order, user, code) {
  if ((order.total > 100 && (user.isFriend || user.isFamily)) || code === "DISCOUNT10") {
    return 0.10
  }
  return 0;
}

Yikes. The code inside the if statement will work, but it can be difficult to read, especially if you're coming back to the code after a few days away from it.

One way to help improve the readability of complex conditions like the one above is to break them up into variables. Using variables can help break up the logic, and the variable name itself can help describe what's happening. Here's one way you could think about rewriting this example:

function getDiscountRate(order, user, code) {
  let isLargeOrderFromFriendOrFamily = order.total > 100 && (user.isFriend || user.isFamily);
  if (isLargeOrderFromFriendOrFamily || code === "DISCOUNT10") {
    return 0.10
  }
  return 0;
}

In this case, we wind up with a bit more code than we had before, but that's okay. We're trying to optimize for readability, not minimum number of lines.

Conclusion

I hope these examples are useful. If you're just beginning to learn to code, I'd encourage you to actively spend time on refactoring. Reviewing your code once it works and looking for places to improve it is a great way to learn.

Have you discovered any other patterns in the way you refactor your code? Let us know!

Written by Matt

Back to all posts

Get Started with Rithm School