A key aspect of software development is making the code base maintainable. If the code is hard to read or understand, it corresponds to an increase in the time to wrap your head around what it’s doing. And since time is money, we can conclude that if code is hard to read/understand, there is a very real increase in cost required to maintain that software.
Nesting Is Your Enemy
Nesting occurs when you open up a new code block. This comes in various forms depending on the language, but is typically your branching, looping, and function definitions. For example, here’s a LOT of nesting:
public String getNameFromDatabase(string id) {
if(id != null) {
if(id.trim() != "") {
Person person = this.database.load(id);
if(person != null) {
if(person.Name != null) {
return person.Name;
} else {
return "";
}
}
}
}
return "";
}
That’s awful. The human brain can only keep so many things in mind at a time, and usually the more contexts that you need to keep in your head at once, the more likely it is that you’ll get lost or make mistakes. Each level of nesting is another context that you’ve got to keep in your head.
What do you do? The solution is often to use early exits.
public String getNameFromDatabase(string id) {
if(id == null) {
return "";
}
if(id.trim() == "") {
return "";
}
var person = this.database.load(id);
if(person == null) {
return "";
}
if(person.Name == null) {
return "";
}
return person.Name;
}
Doing this improves readability and maintainability. You only have to keep at most 1 context in your head at a time. Once you’ve moved beyond that possibility, you can safely forget it and move on to the next one.
Another common (but less severe than the above), and one that junior developers make often is a scenario like this:
public boolean getFoo() {
if(thingX == true && thingY == true) {
return true;
}
return false;
}
Here’s how we can make it a little better:
public boolean getFoo() {
if(thingX && thingY) {
return true;
}
return false;
}
But it can still be even better. Here’s how:
public boolean getFoo() {
return thingX && thingY;
}
It’s a contrived example of course, but illustrates the point. Now there’s no nesting, no unnecessary comparisons, and it’s faster to read and understand. As with all practices and approaches this needs to be considered on a case by case basis because there are certainly cases where a single line return statements actually hurts readability, especially as the branch clause grows larger.
Happy coding.