I’ve been trying really hard to take a lot of care in the code I write these days. I’m fortunate enough to work at a company that strives for quality and understands that the process of writing clean code takes time, exploration and experimentation. One quick tip that I’ve picked up recently is using guards inside my methods. Let me explain.
This article is going to use PHP examples written in Laravel, but if you’re familiar with any C-like language, the concepts are simple and high-level enough that you’ll be able to understand.
The example below is part of a service that filters a listing of events. “Events” as in concerts, conferences, tournaments etc.
The method simply performs a reject on the events that have a primary venue set. Suppose in this imaginary app, an event with a primary venue means that the venue has been confirmed.
$this->request->has('venue_confirmed') is simply checking that
venue_confirmed is in the HTTP request. Perhaps, coming from a checkbox on a form.
What I love about this method, is that thanks to Laravel’s higher order messaging, we only have a single level of indentation. That indentation is the line of code inside the
Why does that matter? Because it’s bad.
Why Indentation is Bad
What if we didn’t have higher order messaging in Laravel? We would have to use the long-form of the Collection’s
This can clearly be cleaned up a bit, even with the long-form,
reject but hopefully, this illustrates a point.
Of course, this can be subjective – and this entire post is – but with 3 levels of indentation this method becomes a lot harder to process.
Code is for humans, not computers.
Not sure who said that first, but it’s repeated time, and time again because it’s constantly forgotten about.
Every time you read into a level of indentation, your brain is having to keep track of one more level of context to the lines of code you’re reading. After even a few levels of nesting, the amount of information you have to retain to understand the code can have a decent cognitive impact.
The more you have to think to understand a function/method in your code base, the sooner you’re going to feel fatigued and unproductive.
Removing indentation from my methods has been the main goal in my day-to-day practice lately. There are many ways to achieve this, but in this post, we’re only going to look at a few, and lastly, what why and how to use guards.
The first tip – and I picked this one up from Jeffery Way’s Laracast videos – is to remove
else when you can.
Look at his code again.
This is something that might be more typical for an entry-level to a junior-level developer to write as a first draft. Some of you might already see clearly that we don’t need this
if statement at all. But just for the sake of argument, pretend that we do.
Even so, why do we even need that
else there? We don’t. If you have an early
return there’s no need for it. It just adds fluff to the code, and now, your eyes have to read into the nesting, out one step, and back in again – yuk!
So let’s scrap that.
Ok cool, that’s a little better. But we haven’t really removed any indentation, even if this is a bit more readable.
With a ternary, we can eliminate that level of indentation completely.
Sweet, now we have 2 levels of indentation – not bad. Of course, as some of you probably already saw, we don’t need a ternary anyway.
We can just return
$event->primaryVenue and this
reject will work perfectly.
With that change, this method honestly doesn’t look that bad. And this next change is highly debatable, but I hate nesting so much, I’ve been making it a habit every time I’m in this exact situation.
What is a Guard
If you read that method again, you’ll notice that we check for some condition to be true, and then perform the bulk of the work. All of the real work is being done inside of the
A guard, is simply the opposite of this approach. Instead of checking if
venue_confirmed is in the request and then doing work, we instead check for if it is not in the request and return early if it isn’t.
Only if the guard doesn’t execute, do we do the real work of the method.
Here’s what our little method looks like with a guard.
You might be thinking, this is more lines of code. And yeah, sure it is. Honestly, I don’t think this is always a bad thing.
A few extra lines of code to avoid unnecessary horizontal reading and nesting is a worthy trade off in my opinion.
Maybe there are more lines, but I can evaluate and determine what this method does faster. Once you get used to seeing guards in your code, you’ll find you can glance over them so fast, and then jump to the meat and potatoes of the method. In this case, it’s the work being done by reject.
Consistency is Key
Back to that original snippet from the beginning of this post.
That there is a clean method. I love how it is concise and easy to read at the same time – often you are sacrificing one for the other. But Laravel’s higher order messaging make these simple little reject and filter operations so damn sexy – I love it!
Even when your framework grants you with magical syntactic pixy dust like that, I would still use a guard in this case. And seriously… the above snippet is probably cleaner looking than using a guard – so I understand how this is going to be met with some push back.
However, one of the simple rules of clean code is being consistent in your style. It’s why we use style guides after all.
You might not love it, but this is what I would do to this method before putting into a pull request:
I didn’t come up with this idea on my own. I’ve been learning a lot from Adam Wathan’s free content and the amazing videos Jeffery Way posts on Laracasts.
Adam Wathan has an amazing book out there that will completely change the way you write PHP. You can get a free sample here: https://adamwathan.me/refactoring-to-collections/
And like all guides or “rules” to writing clean code, this little tip can be and will be abused by early adopters. And that’s exactly what I’m doing these days.
It’s such a sweet looking, simple little pattern that I’m using it everywhere, even when it doesn’t need to be. I don’t even care though – I just love it 😛
What do you think? Are guards cool? Or are you just not as annoyed at indentation as I am?
Leave your comments below!