DEV Community

Mateus Malaquias
Mateus Malaquias

Posted on

Why I like to use Early Returns Pattern?

Thanks to Sarah Kilian @rojekilian for making this photo available freely on Unsplash ๐ŸŽ
Thanks to Sarah Kilian @rojekilian for making this photo available freely on Unsplash ๐ŸŽ

I want to start this article by saying that I didn't like to use early returns in the beginning, however, with time and paring with members of my team, I understood how this simple pattern is strong.

I learned bad habits in my first years as a programmer and, it's OK to develop new ones. Let's see an example from my daily life.

How fast a simple code can mess up everything?

async function getDeliveryType(prod: Product, user: Client) {
  if (prod.isValid()) {
    if (user.isValid()) {
      const address = await getClientAddress(user.id);
      if (address) {
        const fee = await calculateFee(user, address);
        if (fee > 0) {
          return 'delivery';
        } else {
          return 'online';
        }
      } else {
        throw new Error();
      }
    } else {
      throw new Error();
    }
  } else {
    throw new Error();
  }
}
Enter fullscreen mode Exit fullscreen mode

The code above was a simple idea to get the delivery type, this is a perfect example to help us understand the power of applying early returns without messing up the code.

What can we observe in the code?

  • The code isn't linear, if we put more validations will be hard to understand all the conditions.
  • We need to navigate through the ifs to see the positive response.
  • It's confusing to read because of the struct created by if-else.
  • Besides, we get two anti-patterns:ย Else is considered smellyย andย Arrow anti-pattern.

What is an early return?

An approach to keep readability in functions and methods.

๐Ÿ˜‚ Yeah, the answer is pretty simple.

When writing functions or methods, early return means that the expected positive result is returned at the end of the function, and when conditions are not met, the rest of the code ends the execution by returning or throwing an exception.

function sayMyName(name: string): string {
 if (!name || name.length < 0) {
    return;
  }
  return `Hello, ${name}`
}
Enter fullscreen mode Exit fullscreen mode

Refactoring the code to use the Early Returns Pattern

Like I said too many if-else can make it hard to follow the code. I like this approach because the indentation helps me to focus on understanding โ€what this code does?โ€ and not on โ€œwhat's going on here?โ€

Let's refactor the example code.

async function getDeliveryType(prod: Product, user: Client) {
  if (!prod.isValid()) {
    throw new Error();
  }

  if (!user.isValid()) {
    throw new Error();
  }

  const address = await getClientAddress(user.id);

  if (!address) {
    throw new Error();
  }

  const fee = await calculateFee(user, address);
  if (fee > 0) {
    return "delivery";
  }
  return "online";
}
Enter fullscreen mode Exit fullscreen mode

What can we observe now?

  • The code has one indentation level.
  • Itโ€™s easy and fast to read the code.
  • The positive result stays at the end of the function.
  • We can find our logic/business errors first, and in the log term will help us to avoid mistakes and bugs.
  • Now we have a fail-fast design pattern ๐Ÿ™‚.
  • The function ends immediately on errors.
  • With this mindset, we implement a list of design patterns:ย Fail Fast,ย Guard Clause,ย Bouncer Pattern.

Conclusion

I recommend you to adopt as a style guideline, however, this is a subjective thing, so it's your decision whether to use it or not.

Top comments (1)

Collapse
 
rafaelcavalcante profile image
Rafael Cavalcante

๐Ÿ‘