Refactor If Conditions
Doing a lot of refactoring work myself and guiding a group coding bootcamp students through their final project I came across different steps one could take to make the code much cleaner and the app more readable and understandable.
Oftentimes, especially in more complex applications, there is a need to check different conditions. As an example I would use a chess app my stundents were implementing as their final project.
Here is the concrete example: Implement valid_move? method for the rook piece
Thinking through the logic of this method we need to consider following aspects:
- Check if we are actually moving the piece (new coordinates are not the same as current coordinates)
- Check if the new coordinates are inside the chess board (1 to 8 or 0 to 7 depending on the implementation of the board)
- Check if the rook is only moving vertically or horizontally
At this point we don’t care so much whether there is another piece at the destination.
Following the three requirements we would come up with the following implementation:
I once heard that we should make our code readable and understandable for other developers. Other developers is also yourself in two weeks. Now looking at the code I wrote just a few minutes ago it’s already hard for me instantly grasp what the actual conditions are.
The main problem with it is that one needs to make a mental shift between the logic and its implementation. Checking !(new_x == x && new_y == y) is the implementation of a concept of being at different position. While the concept is understandable for humans, the actual implementation of it is not that important.
In one of the weekly iteration episodes of Upcase the Chris and Ian talked exaclty about this topic and discussed different refactoring strategies. Here I want to use one of them claiming that its one of the most important techniques to learn and adopt while being an easy one.
We are going to pull out the if-conditions and replace them with simple method calls giving each one a name. Here is why its a great way to do it:
… if we pull out a chunk of code, then the chunk now needs a name in order to refer to it. […] The more names we can build into your application, the easier it is to build a mental model of what that code is and does.
By applying this simple technique we end up with the following implementation:
Explain it to a 5 year old child
One of the reasons I love this technique so much is that it makes our code human readable. Imagine explaining to a 5 year old the rules to move the rook. You can just open your editor and read the code out loud:
You can move the rook to another position than it is now. You can not move outside the board. You can only move up or down (here you can teach the kid what vertically means) or left or right (horizontally).