One of my pet peeves in programming is that few people use guard clauses. A guard clause is an almost trivial concept that greatly improves readability. Inside a method, handle your special cases right away and return immediately.
Have a look at the following example:
private int doSomething() { if (everythingIsGood()) { /* * Lots and lots of code here, but that's a different story. */ return SOME_VALUE; } else { return ANOTHER_VALUE; // a special case } }
You can easily rewrite it using the Replace Nested Conditional with Guard Clauses refactoring from Martin Fowler’s Refactoring:
private int doSomething() { if (! everythingIsGood()) // <-- this is your guard clause return ANOTHER_VALUE; /* * Lots and lots of code here, but that's a different story. */ return SOME_VALUE; }
Once you’ve read past the conditional(s) at the beginning of the method, you know that your world is in order and you don’t have to worry about special cases anymore.
Good point.
I think this is related to the notion of “fail-fast”, right? Which I wrote about here: http://dlinsin.blogspot.com/2008/07/how-to-fail-fast-on-faulty-injection.html
Yup, it’s definitely related. But catching special cases early can also help to simplify your algorithm, much beyond my trivial example.
I think this is a result of the doctrine that every method should have exactly one exit, which has been tought (and might be tought today) in many programming classes.
While your first example actually has two exits, it’s quite similar to the style that you often see which has one “returnValue” local variable per method and exactly one “return returnValue” statement at the end.
That’s a valid strategy in C to make sure that all memory and locks allocated is freed again. Newer programming languages provide a garbage collector and synchronization has gotten a part of the language. So it’s not that important any more.
@Christoph: Yup. This could perhaps date back to Dijkstra’s “Notes on Structured Programming” from 1969. But if you want to program this way, you should also be forced to provide a correctness proof :)
From my point of view, if everything is not good then it should throw an exception.
If a special case just return a different value because of a different argument then its not a special case to me, that’s just the standard program flow.
Throwing exception will keep best of both world: fail-fast and one return statement per method.
You’ve got the point with the last paragraph – “you know that your world is in order”. The problem with methods is that they accept types that define sets of values that are greater than the set of values the method can handle.
In some cases you can try to reduce the method’s domain like here http://www.codinghelmet.com/?path=howto/why-do-we-need-guard-clauses – if method’s domain is the same as the domain of the type it receives through arguments, then we’re safe and there will be no guard clauses.
Unfortunately, all reference types keep null as part of their domain, and methods must at least guard against nulls then.