Summary
After the episode on leaving a loop without breaking the one-indentation rule, this one tackles nested conditions, the pyramid of doom, on two concrete examples: three nested ifs that act only when everything is true, and a cascade of if and else if that computes a number of days off from a position or a coefficient.
For the first, extracting the conditions into variables is possible but adds tests for nothing. A small assertion function, when, that runs an action if its condition is true and returns that condition, lets the calls chain: each when is called only if the previous one returned true, and the nesting is gone.
For the second, one return per branch would have made SonarQube complain past three returns. The conditions become class accessors, then those accessors return the matching number of days directly, and Math.max picks the result: not one if left in the function.
In both cases the code became more readable and cleaner, which is the point: beautiful code, that works. The unit tests are not shown here, but they must go with every step of the refactoring.
Key ideas
- Nested ifs and long else-if cascades hide the intent and make the code painful to maintain.
- An assertion function that returns its condition turns three levels of nesting into a chain of calls.
- When every branch yields a value, accessors returning that value and a Math.max replace all the branching.
- A refactoring without unit tests is not a refactoring, even if the article does not show them.
Why I wrote this
In the previous episode we had seen how to exit a loop without breaking the Object Calisthenics rule "one level of indentation per method". This article covers two examples of nested ifs and explains, step by step, how to get rid of all those conditional structures.