Development

Refactoring Example – guard clauses (they are used for)

Refactoring Example - guard clauses

I think the best learning way is to try on real causes. Below I will present a case from our real project. How we handle the refactoring of a small part of this older code. This article will not present all the details of this project. A few things have been simplified to make it more understandable.

Story: This part of code is responsible to assing a proper user to the order. We have some assignments in the system. Based on certain conditions, we need to decide whether and to which type of user we should delegate an order. It’s a small “monster” so scroll down as fast as you can…

Few comments about it:

As you can see above, the code is difficult to read or even copy to show to someone else.

Code smells:

  • Long method and class names (more than 3 words. This probably means that we have too much logical responsibility in a single function class).
  • multiple nested conditions + more then 2 indents levels on methods.

The good thing about this situation is that we at least have a flow diagram. It explains the flow of data and the business logic behind it. Comparing the diagram, we see that previously the code was created from top to bottom. (This is probably why it nested the if conditions.)

Refactor decisions:

  • replace nested conditions with guard clauses
  • rename the methods and class using max 3 words (if not possible then it means that the code should be changed/split)
  • tell don’t ask rules

We also decide, that to use guard clauses, we need to start from the goal – so our point is that the destination are the 3 results (no action, delegate to previous, delegate to team), and based on that we will add the guards which check  conditions.

After few renaming iterations and methods changes we reached a first version of refactored code which looks like that:

Comments:

The code is not so neasted, buts it’s still hard to read (to many things going on in this class), it’s to much “procedular” then “OOP”

We made a decision to split it to smaller classes, so that each of two successfull results become a separate object with  it’s own conditions to check. After that the main manager class looks like below. As you can see the main class is quite small and readable now. We have 3 possible results of it, but only two boundaries to check.

  1. Can we delegate to previous user?
  2. Can we delegate to team? And we have the tell – don’t ask rule used.

Those two additional classes looks like below. They are not perfect yet!!! (there is few lines duplicated in the code, but I’m sure you can handle it on your own and made it better (maybe add some interface and extract abstract class? Add some doc block?)  Also I’m sure you can see where the guard clauses are?

Subsequent articles

  • Static Factory Methods aka Named Constructors: Read more…
  • Improving conditions clauses – few small things with hudge impact: Read more…