Visit Sponsor

Written by 7:48 am Clean Code

So You Want Cleaner Code? Nesting Conditionals and Booleans

This post continues the infrequent series on Clean Code examples. If you are enjoying this series, come to CFUnited 2010 and CF.Objective() 2010 to catch my presentation, Making Bad Code Good- Part 2, a live version of this series.

The main idea here is to provide practical examples of working code that can be written in a cleaner fashion. You may agree or disagree with what I’ve written, and I want to hear from you either way in the comments.

If you have a code sample you’d like to see refactored, send it to me through email (if you have my email already).

Code Sample













/>














Read through the entire example and ask yourself the following questions:

  • What is the purpose of this code block? What are you using for your inferences?
  • Is it clear what this code is doing? Why or why not?
  • Can you spot the subtle bug in the code?

Ok, I tricked you, there is no subtle bug in the code. This code sample actually processes like it was intended to and does not have any bugs in it.

Was this code easy to understand? Were you able to follow along with the processing and can you articulate the correct conditions at each branch? Why or why not?

Would you believe that 33% of this code sample is either a <cfif>, <cfelse>, <cfelseif> or a </cfif> tag? Furthermore, at some points in the code, we are nested three levels deep. This confuses me more than anything else in the code, so we’ll start there.

Whenever we refactor, we spend time learning the process expressed by the source code. Since it takes time to gain this learning, it makes sense to stick comments in the relevant sections as we go.

Also, when refactoring, it is very easy to get distracted and make too many changes. Sure there are plenty of things we could change, and we’ll get to it one step at a time. Making too many changes at once is non-scientific and leads to a non-working hot mess. Comprende? Let’s take a look at a refactored example:

Minimizing Nested Conditionals















/>











Better. We got rid of some of the nesting, removed an extra variable and left ourself notes of what this thing actually does.
We’ve definitely improved the code and should be proud of ourselves for sticking to the game plan.
Read over the second code sample once more and ask yourself the same questions again:

  • What is the purpose of this code block? What are you using for your inferences?
  • Is it clear what this code is doing? Why or why not?

At this point, we are being overrun with complex conditionals. Sure we have comments to tell us that structKeyExists( arguments.attributes, “ChallengeAnswer”)
AND structKeyExists( arguments.attributes, “ChallengeQuestionID”)
actually means challenge info was submitted, but the code itself still isn’t very clear. Let’s try to simplify the complex boolean logic.

Removing Complex Boolean Logic















/>











Give that a read. Have your answers changed?

  • What is the purpose of this code block? What are you using for your inferences?
  • Is it clear what this code is doing? Why or why not?

Where did we stick all of the boolean logic? Are there magic code pixies inside the computer sprinkling simplicity dust? Of course not!

We moved the boolean bits into their own separate functions so we can better express the intent of the code, not the inner workings of the code. All the processing in our execute method is at the same level.
The lower level details, the implementation, is tucked away in another level.
Thus:



simply calls:






and this:



simply calls:






Now what?

Sure you may agree this code is cleaner, but when do we have time to work on cleaning up code? Don’t we all have jobs, deadlines and managers with budgets? Consider this:

If we spend much of our time maintaining applications, this means we are either fixing bugs, or bolting on yet another feature to an existing application.
By design, we are always reading code, keeping the entire problem context in our brain while we try to figure out how the heck it works.
By using the techniques above, cleaning up code as we go, we take advantage of the hard earned understanding of how a piece of code works.
Now, you can fix the bug or add the new feature without having to keep a huge problem map in your brain (this especially helps when you are bombarded with emails, twitter alerts, IM, phone calls, and pesky managers with their pesky project plan questions :).

Just keep in mind these simple rules:

  • Focus on High Value changes leading to better code cleanliness and structure
  • Stay focused in your changes. Improve one concept at a time
  • Stay away from renaming variables, changing intentations, replacing tabs with spaces, or other personal preference changes. Leave that for when you have extra time
  • Reread your code samples aloud, you’ll often be surprised by how hard this is. (You have more experience reading, since you started reading at 2, and coding at 20 )
  • Work smarter, not harder. Refactor for peace of mind.

This code isn’t perfect yet and I bet you can improve the last code sample even more. If you want to have a go, email your code sample and explanation to me. I’ll post it here. (Be sure to reference the title of this post in your email)

Visited 7,933 times, 1 visit(s) today
[mc4wp_form id="5878"]
Close