Tue 6 Sep 2011
Clean Code – Bang is Evil
To disambiguate the title, I’m referring to exclamation points when I say bang. I’m specifically referring to bangs in programming languages with C-style syntax. For the non-programmers in our readership, exclamation points can be thought of as meaning “not”. Bangs impede readability and in most cases readability is the most important -ility.
I’ll admit at this point that this post might seem a bit cheap. You might think it’s just a refinement of my previous post on composed methods, offering an explanation for some of the choices you can make when working toward composed methods. I admit that this post is not exclusively about bangs. Stay tuned and you might learn something.
Take this example, in Java-like pseudocode. It’s a very simple example, but it provides plenty of content for discussion.
public void doSomething(SomeClass anObject) {
if(anObject.someRelation() != null
&& anObject.state() != “Holy Crap Don’t Do Something!”) {
anObject.doSomething();
}
}
First, what does it mean if someRelation() returns null? Why is it important if it returns a non-null value? How many places in your codebase are you going to write this same if statement?
What you should be doing is taking someRelation() != null and turning it into hasRelation(). There is a certain mental parsing difficulty associated with bangs. No matter how much time you’ve spent programming and no matter how familiar you are with the codebase, figuring out that someRelation != null really means hasRelation() is going to take a second.
The generalization here is to take any expression involving a bang and convert it to a method.
Ok, now we have this:
public void doSomething(SomeClass anObject) {
if(anObject.hasRelation()
&& anObject.state() != “Holy Crap Don’t Do Something!”) {
anObject.doSomething();
}
}
That’s a definite improvement in readability, but we’re still banging within our conditional. That’s evil. For now, let’s ignore the fact that we’re comparing to a magic string.
This is going to sound a bit redundant, but what does anObject.state() != “Holy Crap Don’t Do Something!” mean? Specifically, the double bang causes all the same problems that a double negative does in English. Don’t see the second bang? It’s in the string literal. The resolution is to express the conditional as another method on SomeClass, like this: anObject.shouldDoSomething().
Now we’re doing better:
public void doSomething(SomeClass anObject) {
if(anObject.hasRelation() && anObject.shouldDoSomething()) {
anObject.doSomething();
}
}
There’s still something that’s fishy here. I’m not talking about the compound conditional – that’s a topic for another post. We have a method, presumably not located on SomeClass, that accepts an instance of SomeClass and examines it. Depending on the results of that examination, it acts on that instance. It does nothing else.
As I warned, this post isn’t exclusively about bangs. Here’s where we jump off the rails.
If a method on class A does nothing but interrogate and act on class B, then the method probably belongs on class B. I’m not claiming to have invented this idea, but I did come up with this as my personal guideline for when to apply it: if you can turn any method into a private static method, then it should probably be a public instance method on another class. In our example above, the doSomething method probably belongs on SomeClass.
This post has meandered a bit, so here’s a summary:
- If you have a bang in a conditional, convert it to a method
- If a conditional has a double negative, convert it to a method that hides the double negative (returns the positive) and has a name that suggests as much
- Avoid compound conditionals
- If after you finish extracting methods, you end up with any methods that can be made private static, move them to the class of their most used parameter (or whatever makes the most sense) and make them public instance methods
Incidentally, I hate any method where the entire body is contained in an “if” block. My final example contains exactly that. I would prefer to see a guard clause and an early return. It also contains a compound conditional. I would prefer to see a single method call there. Both of those are topics for another post.

Agreed completely on avoiding double-negatives. Here’s a good example of what double-negatives lead to:
http://joshcarter.com/software/tortured_logic_visual_basic_st